@poe-platform/safe-bash 0.1.511 → 0.1.513
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/safe-bash/chunks/{chunk-5HT35GTV.js → chunk-5MSOBYRG.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-B637PJBS.js → chunk-5OCQTFXT.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-B637PJBS.js.map → chunk-5OCQTFXT.js.map} +2 -2
- package/dist/safe-bash/chunks/{chunk-4OKU6JXB.js → chunk-NYHAKXQ7.js} +2 -2
- package/dist/safe-bash/commands/cmp.d.ts +3 -0
- package/dist/safe-bash/commands/cmp.d.ts.map +1 -0
- package/dist/safe-bash/commands/cmp.js +595 -0
- package/dist/safe-bash/commands/cmp.js.map +1 -0
- package/dist/safe-bash/commands/fmt.d.ts +3 -0
- package/dist/safe-bash/commands/fmt.d.ts.map +1 -0
- package/dist/safe-bash/commands/fmt.js +839 -0
- package/dist/safe-bash/commands/fmt.js.map +1 -0
- package/dist/safe-bash/commands/metadata/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/metadata/index.js +2 -1
- package/dist/safe-bash/commands/metadata/index.js.map +1 -1
- package/dist/safe-bash/commands/numfmt.d.ts +3 -0
- package/dist/safe-bash/commands/numfmt.d.ts.map +1 -0
- package/dist/safe-bash/commands/numfmt.js +1180 -0
- package/dist/safe-bash/commands/numfmt.js.map +1 -0
- package/dist/safe-bash/commands/regex-execution/bounded-provider.d.ts +1 -1
- package/dist/safe-bash/commands/regex-execution/bounded-provider.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/bounded-provider.js +7 -35
- package/dist/safe-bash/commands/regex-execution/bounded-provider.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/matcher.d.ts +2 -0
- package/dist/safe-bash/commands/regex-execution/ere/matcher.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/matcher.js +55 -1
- package/dist/safe-bash/commands/regex-execution/ere/matcher.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/syntax.js +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/syntax.js.map +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/types.d.ts +1 -0
- package/dist/safe-bash/commands/regex-execution/ere/types.d.ts.map +1 -1
- package/dist/safe-bash/commands/regex-execution/utf8.d.ts +3 -0
- package/dist/safe-bash/commands/regex-execution/utf8.d.ts.map +1 -0
- package/dist/safe-bash/commands/regex-execution/utf8.js +24 -0
- package/dist/safe-bash/commands/regex-execution/utf8.js.map +1 -0
- package/dist/safe-bash/commands/shuf.d.ts +3 -0
- package/dist/safe-bash/commands/shuf.d.ts.map +1 -0
- package/dist/safe-bash/commands/shuf.js +768 -0
- package/dist/safe-bash/commands/shuf.js.map +1 -0
- package/dist/safe-bash/commands/standard.d.ts.map +1 -1
- package/dist/safe-bash/commands/standard.js +5 -0
- package/dist/safe-bash/commands/standard.js.map +1 -1
- package/dist/safe-bash/commands/truncate.d.ts +4 -0
- package/dist/safe-bash/commands/truncate.d.ts.map +1 -0
- package/dist/safe-bash/commands/truncate.js +668 -0
- package/dist/safe-bash/commands/truncate.js.map +1 -0
- package/dist/safe-bash/commands/which/which.d.ts.map +1 -1
- package/dist/safe-bash/commands/which/which.js +1 -0
- package/dist/safe-bash/commands/which/which.js.map +1 -1
- package/dist/safe-bash/commands/xml/index.browser.js +2 -2
- package/dist/safe-bash/commands/yq/index.browser.js +2 -2
- package/dist/safe-bash/contracts/command.d.ts +11 -1
- package/dist/safe-bash/contracts/command.d.ts.map +1 -1
- package/dist/safe-bash/contracts/command.js.map +1 -1
- package/dist/safe-bash/contracts/filesystem.d.ts +1 -1
- package/dist/safe-bash/contracts/filesystem.d.ts.map +1 -1
- package/dist/safe-bash/core.browser.js +9481 -789
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/dist/safe-bash/shell/input.d.ts +15 -4
- package/dist/safe-bash/shell/input.d.ts.map +1 -1
- package/dist/safe-bash/shell/input.js +211 -9
- package/dist/safe-bash/shell/input.js.map +1 -1
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +16 -4
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/package.json +2 -2
- /package/dist/safe-bash/chunks/{chunk-5HT35GTV.js.map → chunk-5MSOBYRG.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-4OKU6JXB.js.map → chunk-NYHAKXQ7.js.map} +0 -0
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
import { FsError, getCommandArguments, writeBytes } from "../contracts/index.js";
|
|
2
|
+
import { createOutputOperation } from "../contracts/output.js";
|
|
3
|
+
import { shellValueByteLength } from "../contracts/value.js";
|
|
4
|
+
import { yieldTurn } from "../contracts/yield.js";
|
|
5
|
+
import { PublicDiagnostic, publicDiagnosticMessage } from "../diagnostics.js";
|
|
6
|
+
import { bufferLimit, pathOf } from "./internal.js";
|
|
7
|
+
import { settings as metadataSettings } from "./metadata/internal.js";
|
|
8
|
+
const signedMaximum = (1n << 63n) - 1n;
|
|
9
|
+
const signedMinimum = -signedMaximum - 1n;
|
|
10
|
+
const helpText = "Usage: truncate OPTION... FILE...\nShrink or extend the size of each FILE to the specified size\n\nA FILE argument that does not exist is created.\n\nIf a FILE is larger than the specified size, the extra data is lost.\nIf a FILE is shorter, it is extended and the extended part (hole)\nreads as zero bytes.\n\nMandatory arguments to long options are mandatory for short options too.\n -c, --no-create do not create any files\n -o, --io-blocks treat SIZE as number of IO blocks instead of bytes\n -r, --reference=RFILE base size on RFILE\n -s, --size=SIZE set or adjust the file size by SIZE bytes\n --help display this help and exit\n --version output version information and exit\n\nThe SIZE argument is an integer and optional unit (example: 10K is 10*1024).\nUnits are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).\n\nSIZE may also be prefixed by one of the following modifying characters:\n'+' extend by, '-' reduce by, '<' at most, '>' at least,\n'/' round down to multiple of, '%' round up to multiple of.\n\nGNU coreutils online help: <https://www.gnu.org/software/coreutils/>\nReport truncate translation bugs to <https://translationproject.org/team/>\nFull documentation at: <https://www.gnu.org/software/coreutils/truncate>\nor available locally via: info '(coreutils) truncate invocation'\n";
|
|
11
|
+
const glibc231PrintableRanges = [
|
|
12
|
+
0x20, 0x7e, 0xa0, 0x377, 0x37a, 0x37f, 0x384, 0x38a, 0x38c, 0x38c, 0x38e, 0x3a1, 0x3a3, 0x52f, 0x531, 0x556,
|
|
13
|
+
0x559, 0x55f, 0x561, 0x587, 0x589, 0x58a, 0x58d, 0x58f, 0x591, 0x5c7, 0x5d0, 0x5ea, 0x5f0, 0x5f4, 0x600, 0x61c,
|
|
14
|
+
0x61e, 0x70d, 0x70f, 0x74a, 0x74d, 0x7b1, 0x7c0, 0x7fa, 0x800, 0x82d, 0x830, 0x83e, 0x840, 0x85b, 0x85e, 0x85e,
|
|
15
|
+
0x8a0, 0x8b4, 0x8b6, 0x8bd, 0x8d4, 0x983, 0x985, 0x98c, 0x98f, 0x990, 0x993, 0x9a8, 0x9aa, 0x9b0, 0x9b2, 0x9b2,
|
|
16
|
+
0x9b6, 0x9b9, 0x9bc, 0x9c4, 0x9c7, 0x9c8, 0x9cb, 0x9ce, 0x9d7, 0x9d7, 0x9dc, 0x9dd, 0x9df, 0x9e3, 0x9e6, 0x9fb,
|
|
17
|
+
0xa01, 0xa03, 0xa05, 0xa0a, 0xa0f, 0xa10, 0xa13, 0xa28, 0xa2a, 0xa30, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39,
|
|
18
|
+
0xa3c, 0xa3c, 0xa3e, 0xa42, 0xa47, 0xa48, 0xa4b, 0xa4d, 0xa51, 0xa51, 0xa59, 0xa5c, 0xa5e, 0xa5e, 0xa66, 0xa75,
|
|
19
|
+
0xa81, 0xa83, 0xa85, 0xa8d, 0xa8f, 0xa91, 0xa93, 0xaa8, 0xaaa, 0xab0, 0xab2, 0xab3, 0xab5, 0xab9, 0xabc, 0xac5,
|
|
20
|
+
0xac7, 0xac9, 0xacb, 0xacd, 0xad0, 0xad0, 0xae0, 0xae3, 0xae6, 0xaf1, 0xaf9, 0xaf9, 0xb01, 0xb03, 0xb05, 0xb0c,
|
|
21
|
+
0xb0f, 0xb10, 0xb13, 0xb28, 0xb2a, 0xb30, 0xb32, 0xb33, 0xb35, 0xb39, 0xb3c, 0xb44, 0xb47, 0xb48, 0xb4b, 0xb4d,
|
|
22
|
+
0xb56, 0xb57, 0xb5c, 0xb5d, 0xb5f, 0xb63, 0xb66, 0xb77, 0xb82, 0xb83, 0xb85, 0xb8a, 0xb8e, 0xb90, 0xb92, 0xb95,
|
|
23
|
+
0xb99, 0xb9a, 0xb9c, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xba8, 0xbaa, 0xbae, 0xbb9, 0xbbe, 0xbc2, 0xbc6, 0xbc8,
|
|
24
|
+
0xbca, 0xbcd, 0xbd0, 0xbd0, 0xbd7, 0xbd7, 0xbe6, 0xbfa, 0xc00, 0xc03, 0xc05, 0xc0c, 0xc0e, 0xc10, 0xc12, 0xc28,
|
|
25
|
+
0xc2a, 0xc39, 0xc3d, 0xc44, 0xc46, 0xc48, 0xc4a, 0xc4d, 0xc55, 0xc56, 0xc58, 0xc5a, 0xc60, 0xc63, 0xc66, 0xc6f,
|
|
26
|
+
0xc78, 0xc83, 0xc85, 0xc8c, 0xc8e, 0xc90, 0xc92, 0xca8, 0xcaa, 0xcb3, 0xcb5, 0xcb9, 0xcbc, 0xcc4, 0xcc6, 0xcc8,
|
|
27
|
+
0xcca, 0xccd, 0xcd5, 0xcd6, 0xcde, 0xcde, 0xce0, 0xce3, 0xce6, 0xcef, 0xcf1, 0xcf2, 0xd01, 0xd03, 0xd05, 0xd0c,
|
|
28
|
+
0xd0e, 0xd10, 0xd12, 0xd3a, 0xd3d, 0xd44, 0xd46, 0xd48, 0xd4a, 0xd4f, 0xd54, 0xd63, 0xd66, 0xd7f, 0xd82, 0xd83,
|
|
29
|
+
0xd85, 0xd96, 0xd9a, 0xdb1, 0xdb3, 0xdbb, 0xdbd, 0xdbd, 0xdc0, 0xdc6, 0xdca, 0xdca, 0xdcf, 0xdd4, 0xdd6, 0xdd6,
|
|
30
|
+
0xdd8, 0xddf, 0xde6, 0xdef, 0xdf2, 0xdf4, 0xe01, 0xe3a, 0xe3f, 0xe5b, 0xe81, 0xe82, 0xe84, 0xe84, 0xe87, 0xe88,
|
|
31
|
+
0xe8a, 0xe8a, 0xe8d, 0xe8d, 0xe94, 0xe97, 0xe99, 0xe9f, 0xea1, 0xea3, 0xea5, 0xea5, 0xea7, 0xea7, 0xeaa, 0xeab,
|
|
32
|
+
0xead, 0xeb9, 0xebb, 0xebd, 0xec0, 0xec4, 0xec6, 0xec6, 0xec8, 0xecd, 0xed0, 0xed9, 0xedc, 0xedf, 0xf00, 0xf47,
|
|
33
|
+
0xf49, 0xf6c, 0xf71, 0xf97, 0xf99, 0xfbc, 0xfbe, 0xfcc, 0xfce, 0xfda, 0x1000, 0x10c5, 0x10c7, 0x10c7, 0x10cd, 0x10cd,
|
|
34
|
+
0x10d0, 0x1248, 0x124a, 0x124d, 0x1250, 0x1256, 0x1258, 0x1258, 0x125a, 0x125d, 0x1260, 0x1288, 0x128a, 0x128d, 0x1290, 0x12b0,
|
|
35
|
+
0x12b2, 0x12b5, 0x12b8, 0x12be, 0x12c0, 0x12c0, 0x12c2, 0x12c5, 0x12c8, 0x12d6, 0x12d8, 0x1310, 0x1312, 0x1315, 0x1318, 0x135a,
|
|
36
|
+
0x135d, 0x137c, 0x1380, 0x1399, 0x13a0, 0x13f5, 0x13f8, 0x13fd, 0x1400, 0x169c, 0x16a0, 0x16f8, 0x1700, 0x170c, 0x170e, 0x1714,
|
|
37
|
+
0x1720, 0x1736, 0x1740, 0x1753, 0x1760, 0x176c, 0x176e, 0x1770, 0x1772, 0x1773, 0x1780, 0x17dd, 0x17e0, 0x17e9, 0x17f0, 0x17f9,
|
|
38
|
+
0x1800, 0x180e, 0x1810, 0x1819, 0x1820, 0x1877, 0x1880, 0x18aa, 0x18b0, 0x18f5, 0x1900, 0x191e, 0x1920, 0x192b, 0x1930, 0x193b,
|
|
39
|
+
0x1940, 0x1940, 0x1944, 0x196d, 0x1970, 0x1974, 0x1980, 0x19ab, 0x19b0, 0x19c9, 0x19d0, 0x19da, 0x19de, 0x1a1b, 0x1a1e, 0x1a5e,
|
|
40
|
+
0x1a60, 0x1a7c, 0x1a7f, 0x1a89, 0x1a90, 0x1a99, 0x1aa0, 0x1aad, 0x1ab0, 0x1abe, 0x1b00, 0x1b4b, 0x1b50, 0x1b7c, 0x1b80, 0x1bf3,
|
|
41
|
+
0x1bfc, 0x1c37, 0x1c3b, 0x1c49, 0x1c4d, 0x1c88, 0x1cc0, 0x1cc7, 0x1cd0, 0x1cf6, 0x1cf8, 0x1cf9, 0x1d00, 0x1df5, 0x1dfb, 0x1f15,
|
|
42
|
+
0x1f18, 0x1f1d, 0x1f20, 0x1f45, 0x1f48, 0x1f4d, 0x1f50, 0x1f57, 0x1f59, 0x1f59, 0x1f5b, 0x1f5b, 0x1f5d, 0x1f5d, 0x1f5f, 0x1f7d,
|
|
43
|
+
0x1f80, 0x1fb4, 0x1fb6, 0x1fc4, 0x1fc6, 0x1fd3, 0x1fd6, 0x1fdb, 0x1fdd, 0x1fef, 0x1ff2, 0x1ff4, 0x1ff6, 0x1ffe, 0x2000, 0x2027,
|
|
44
|
+
0x202a, 0x2064, 0x2066, 0x2071, 0x2074, 0x208e, 0x2090, 0x209c, 0x20a0, 0x20be, 0x20d0, 0x20f0, 0x2100, 0x218b, 0x2190, 0x23fe,
|
|
45
|
+
0x2400, 0x2426, 0x2440, 0x244a, 0x2460, 0x2b73, 0x2b76, 0x2b95, 0x2b98, 0x2bb9, 0x2bbd, 0x2bc8, 0x2bca, 0x2bd1, 0x2bec, 0x2bef,
|
|
46
|
+
0x2c00, 0x2c2e, 0x2c30, 0x2c5e, 0x2c60, 0x2cf3, 0x2cf9, 0x2d25, 0x2d27, 0x2d27, 0x2d2d, 0x2d2d, 0x2d30, 0x2d67, 0x2d6f, 0x2d70,
|
|
47
|
+
0x2d7f, 0x2d96, 0x2da0, 0x2da6, 0x2da8, 0x2dae, 0x2db0, 0x2db6, 0x2db8, 0x2dbe, 0x2dc0, 0x2dc6, 0x2dc8, 0x2dce, 0x2dd0, 0x2dd6,
|
|
48
|
+
0x2dd8, 0x2dde, 0x2de0, 0x2e44, 0x2e80, 0x2e99, 0x2e9b, 0x2ef3, 0x2f00, 0x2fd5, 0x2ff0, 0x2ffb, 0x3000, 0x303f, 0x3041, 0x3096,
|
|
49
|
+
0x3099, 0x30ff, 0x3105, 0x312d, 0x3131, 0x318e, 0x3190, 0x31ba, 0x31c0, 0x31e3, 0x31f0, 0x321e, 0x3220, 0x32fe, 0x3300, 0x4db5,
|
|
50
|
+
0x4dc0, 0x9fd5, 0xa000, 0xa48c, 0xa490, 0xa4c6, 0xa4d0, 0xa62b, 0xa640, 0xa6f7, 0xa700, 0xa7ae, 0xa7b0, 0xa7b7, 0xa7f7, 0xa82b,
|
|
51
|
+
0xa830, 0xa839, 0xa840, 0xa877, 0xa880, 0xa8c5, 0xa8ce, 0xa8d9, 0xa8e0, 0xa8fd, 0xa900, 0xa953, 0xa95f, 0xa97c, 0xa980, 0xa9cd,
|
|
52
|
+
0xa9cf, 0xa9d9, 0xa9de, 0xa9fe, 0xaa00, 0xaa36, 0xaa40, 0xaa4d, 0xaa50, 0xaa59, 0xaa5c, 0xaac2, 0xaadb, 0xaaf6, 0xab01, 0xab06,
|
|
53
|
+
0xab09, 0xab0e, 0xab11, 0xab16, 0xab20, 0xab26, 0xab28, 0xab2e, 0xab30, 0xab65, 0xab70, 0xabed, 0xabf0, 0xabf9, 0xac00, 0xd7a3,
|
|
54
|
+
0xd7b0, 0xd7c6, 0xd7cb, 0xd7fb, 0xe000, 0xfa6d, 0xfa70, 0xfad9, 0xfb00, 0xfb06, 0xfb13, 0xfb17, 0xfb1d, 0xfb36, 0xfb38, 0xfb3c,
|
|
55
|
+
0xfb3e, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfb46, 0xfbc1, 0xfbd3, 0xfd3f, 0xfd50, 0xfd8f, 0xfd92, 0xfdc7, 0xfdf0, 0xfdfd,
|
|
56
|
+
0xfe00, 0xfe19, 0xfe20, 0xfe52, 0xfe54, 0xfe66, 0xfe68, 0xfe6b, 0xfe70, 0xfe74, 0xfe76, 0xfefc, 0xfeff, 0xfeff, 0xff01, 0xffbe,
|
|
57
|
+
0xffc2, 0xffc7, 0xffca, 0xffcf, 0xffd2, 0xffd7, 0xffda, 0xffdc, 0xffe0, 0xffe6, 0xffe8, 0xffee, 0xfff9, 0xfffd, 0x10000, 0x1000b,
|
|
58
|
+
0x1000d, 0x10026, 0x10028, 0x1003a, 0x1003c, 0x1003d, 0x1003f, 0x1004d, 0x10050, 0x1005d, 0x10080, 0x100fa, 0x10100, 0x10102, 0x10107, 0x10133,
|
|
59
|
+
0x10137, 0x1018e, 0x10190, 0x1019b, 0x101a0, 0x101a0, 0x101d0, 0x101fd, 0x10280, 0x1029c, 0x102a0, 0x102d0, 0x102e0, 0x102fb, 0x10300, 0x10323,
|
|
60
|
+
0x10330, 0x1034a, 0x10350, 0x1037a, 0x10380, 0x1039d, 0x1039f, 0x103c3, 0x103c8, 0x103d5, 0x10400, 0x1049d, 0x104a0, 0x104a9, 0x104b0, 0x104d3,
|
|
61
|
+
0x104d8, 0x104fb, 0x10500, 0x10527, 0x10530, 0x10563, 0x1056f, 0x1056f, 0x10600, 0x10736, 0x10740, 0x10755, 0x10760, 0x10767, 0x10800, 0x10805,
|
|
62
|
+
0x10808, 0x10808, 0x1080a, 0x10835, 0x10837, 0x10838, 0x1083c, 0x1083c, 0x1083f, 0x10855, 0x10857, 0x1089e, 0x108a7, 0x108af, 0x108e0, 0x108f2,
|
|
63
|
+
0x108f4, 0x108f5, 0x108fb, 0x1091b, 0x1091f, 0x10939, 0x1093f, 0x1093f, 0x10980, 0x109b7, 0x109bc, 0x109cf, 0x109d2, 0x10a03, 0x10a05, 0x10a06,
|
|
64
|
+
0x10a0c, 0x10a13, 0x10a15, 0x10a17, 0x10a19, 0x10a33, 0x10a38, 0x10a3a, 0x10a3f, 0x10a47, 0x10a50, 0x10a58, 0x10a60, 0x10a9f, 0x10ac0, 0x10ae6,
|
|
65
|
+
0x10aeb, 0x10af6, 0x10b00, 0x10b35, 0x10b39, 0x10b55, 0x10b58, 0x10b72, 0x10b78, 0x10b91, 0x10b99, 0x10b9c, 0x10ba9, 0x10baf, 0x10c00, 0x10c48,
|
|
66
|
+
0x10c80, 0x10cb2, 0x10cc0, 0x10cf2, 0x10cfa, 0x10cff, 0x10e60, 0x10e7e, 0x11000, 0x1104d, 0x11052, 0x1106f, 0x1107f, 0x110c1, 0x110d0, 0x110e8,
|
|
67
|
+
0x110f0, 0x110f9, 0x11100, 0x11134, 0x11136, 0x11143, 0x11150, 0x11176, 0x11180, 0x111cd, 0x111d0, 0x111df, 0x111e1, 0x111f4, 0x11200, 0x11211,
|
|
68
|
+
0x11213, 0x1123e, 0x11280, 0x11286, 0x11288, 0x11288, 0x1128a, 0x1128d, 0x1128f, 0x1129d, 0x1129f, 0x112a9, 0x112b0, 0x112ea, 0x112f0, 0x112f9,
|
|
69
|
+
0x11300, 0x11303, 0x11305, 0x1130c, 0x1130f, 0x11310, 0x11313, 0x11328, 0x1132a, 0x11330, 0x11332, 0x11333, 0x11335, 0x11339, 0x1133c, 0x11344,
|
|
70
|
+
0x11347, 0x11348, 0x1134b, 0x1134d, 0x11350, 0x11350, 0x11357, 0x11357, 0x1135d, 0x11363, 0x11366, 0x1136c, 0x11370, 0x11374, 0x11400, 0x11459,
|
|
71
|
+
0x1145b, 0x1145b, 0x1145d, 0x1145d, 0x11480, 0x114c7, 0x114d0, 0x114d9, 0x11580, 0x115b5, 0x115b8, 0x115dd, 0x11600, 0x11644, 0x11650, 0x11659,
|
|
72
|
+
0x11660, 0x1166c, 0x11680, 0x116b7, 0x116c0, 0x116c9, 0x11700, 0x11719, 0x1171d, 0x1172b, 0x11730, 0x1173f, 0x118a0, 0x118f2, 0x118ff, 0x118ff,
|
|
73
|
+
0x11ac0, 0x11af8, 0x11c00, 0x11c08, 0x11c0a, 0x11c36, 0x11c38, 0x11c45, 0x11c50, 0x11c6c, 0x11c70, 0x11c8f, 0x11c92, 0x11ca7, 0x11ca9, 0x11cb6,
|
|
74
|
+
0x12000, 0x12399, 0x12400, 0x1246e, 0x12470, 0x12474, 0x12480, 0x12543, 0x13000, 0x1342e, 0x14400, 0x14646, 0x16800, 0x16a38, 0x16a40, 0x16a5e,
|
|
75
|
+
0x16a60, 0x16a69, 0x16a6e, 0x16a6f, 0x16ad0, 0x16aed, 0x16af0, 0x16af5, 0x16b00, 0x16b45, 0x16b50, 0x16b59, 0x16b5b, 0x16b61, 0x16b63, 0x16b77,
|
|
76
|
+
0x16b7d, 0x16b8f, 0x16f00, 0x16f44, 0x16f50, 0x16f7e, 0x16f8f, 0x16f9f, 0x16fe0, 0x16fe0, 0x17000, 0x187ec, 0x18800, 0x18af2, 0x1b000, 0x1b001,
|
|
77
|
+
0x1bc00, 0x1bc6a, 0x1bc70, 0x1bc7c, 0x1bc80, 0x1bc88, 0x1bc90, 0x1bc99, 0x1bc9c, 0x1bca3, 0x1d000, 0x1d0f5, 0x1d100, 0x1d126, 0x1d129, 0x1d1e8,
|
|
78
|
+
0x1d200, 0x1d245, 0x1d300, 0x1d356, 0x1d360, 0x1d371, 0x1d400, 0x1d454, 0x1d456, 0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a2, 0x1d4a5, 0x1d4a6,
|
|
79
|
+
0x1d4a9, 0x1d4ac, 0x1d4ae, 0x1d4b9, 0x1d4bb, 0x1d4bb, 0x1d4bd, 0x1d4c3, 0x1d4c5, 0x1d505, 0x1d507, 0x1d50a, 0x1d50d, 0x1d514, 0x1d516, 0x1d51c,
|
|
80
|
+
0x1d51e, 0x1d539, 0x1d53b, 0x1d53e, 0x1d540, 0x1d544, 0x1d546, 0x1d546, 0x1d54a, 0x1d550, 0x1d552, 0x1d6a5, 0x1d6a8, 0x1d7cb, 0x1d7ce, 0x1da8b,
|
|
81
|
+
0x1da9b, 0x1da9f, 0x1daa1, 0x1daaf, 0x1e000, 0x1e006, 0x1e008, 0x1e018, 0x1e01b, 0x1e021, 0x1e023, 0x1e024, 0x1e026, 0x1e02a, 0x1e800, 0x1e8c4,
|
|
82
|
+
0x1e8c7, 0x1e8d6, 0x1e900, 0x1e94a, 0x1e950, 0x1e959, 0x1e95e, 0x1e95f, 0x1ee00, 0x1ee03, 0x1ee05, 0x1ee1f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee24,
|
|
83
|
+
0x1ee27, 0x1ee27, 0x1ee29, 0x1ee32, 0x1ee34, 0x1ee37, 0x1ee39, 0x1ee39, 0x1ee3b, 0x1ee3b, 0x1ee42, 0x1ee42, 0x1ee47, 0x1ee47, 0x1ee49, 0x1ee49,
|
|
84
|
+
0x1ee4b, 0x1ee4b, 0x1ee4d, 0x1ee4f, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee54, 0x1ee57, 0x1ee57, 0x1ee59, 0x1ee59, 0x1ee5b, 0x1ee5b, 0x1ee5d, 0x1ee5d,
|
|
85
|
+
0x1ee5f, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee64, 0x1ee67, 0x1ee6a, 0x1ee6c, 0x1ee72, 0x1ee74, 0x1ee77, 0x1ee79, 0x1ee7c, 0x1ee7e, 0x1ee7e,
|
|
86
|
+
0x1ee80, 0x1ee89, 0x1ee8b, 0x1ee9b, 0x1eea1, 0x1eea3, 0x1eea5, 0x1eea9, 0x1eeab, 0x1eebb, 0x1eef0, 0x1eef1, 0x1f000, 0x1f02b, 0x1f030, 0x1f093,
|
|
87
|
+
0x1f0a0, 0x1f0ae, 0x1f0b1, 0x1f0bf, 0x1f0c1, 0x1f0cf, 0x1f0d1, 0x1f0f5, 0x1f100, 0x1f10c, 0x1f110, 0x1f12e, 0x1f130, 0x1f16b, 0x1f170, 0x1f1ac,
|
|
88
|
+
0x1f1e6, 0x1f202, 0x1f210, 0x1f23b, 0x1f240, 0x1f248, 0x1f250, 0x1f251, 0x1f300, 0x1f6d2, 0x1f6e0, 0x1f6ec, 0x1f6f0, 0x1f6f6, 0x1f700, 0x1f773,
|
|
89
|
+
0x1f780, 0x1f7d4, 0x1f800, 0x1f80b, 0x1f810, 0x1f847, 0x1f850, 0x1f859, 0x1f860, 0x1f887, 0x1f890, 0x1f8ad, 0x1f910, 0x1f91e, 0x1f920, 0x1f927,
|
|
90
|
+
0x1f930, 0x1f930, 0x1f933, 0x1f93e, 0x1f940, 0x1f94b, 0x1f950, 0x1f95e, 0x1f980, 0x1f991, 0x1f9c0, 0x1f9c0, 0x20000, 0x2a6d6, 0x2a700, 0x2b734,
|
|
91
|
+
0x2b740, 0x2b81d, 0x2b820, 0x2cea1, 0x2f800, 0x2fa1d, 0xe0001, 0xe0001, 0xe0020, 0xe007f, 0xe0100, 0xe01ef, 0xf0000, 0xffffd, 0x100000, 0x10fffd,
|
|
92
|
+
];
|
|
93
|
+
class TruncateDiagnostic extends Error {
|
|
94
|
+
detail;
|
|
95
|
+
usage;
|
|
96
|
+
constructor(detail, usage = false) {
|
|
97
|
+
super(detail);
|
|
98
|
+
this.detail = detail;
|
|
99
|
+
this.usage = usage;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function unicodeLocale(context) {
|
|
103
|
+
const locale = (context.env.LC_ALL || context.env.LC_CTYPE || context.env.LANG || "C").toLowerCase();
|
|
104
|
+
return locale.endsWith("utf-8") || locale.endsWith("utf8");
|
|
105
|
+
}
|
|
106
|
+
function quote(text, filename = false, unicode = false) {
|
|
107
|
+
const controls = { "\u0007": "\\a", "\b": "\\b", "\t": "\\t", "\n": "\\n", "\v": "\\v", "\f": "\\f", "\r": "\\r" };
|
|
108
|
+
const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
109
|
+
const units = [];
|
|
110
|
+
for (let offset = 0; offset < text.length;) {
|
|
111
|
+
const first = text.charCodeAt(offset);
|
|
112
|
+
let length = 1;
|
|
113
|
+
let point = first;
|
|
114
|
+
let valid = first < 128;
|
|
115
|
+
if (unicode && first >= 0xc2 && first <= 0xf4) {
|
|
116
|
+
const size = first < 0xe0 ? 2 : first < 0xf0 ? 3 : 4;
|
|
117
|
+
try {
|
|
118
|
+
point = decoder.decode(Uint8Array.from(text.slice(offset, offset + size), character => character.charCodeAt(0))).codePointAt(0);
|
|
119
|
+
length = size;
|
|
120
|
+
valid = true;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
valid = false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
let printable = valid && point >= 32 && point < 127;
|
|
127
|
+
if (valid && point >= 128) {
|
|
128
|
+
let low = 0, high = glibc231PrintableRanges.length / 2;
|
|
129
|
+
while (low < high) {
|
|
130
|
+
const middle = Math.floor((low + high) / 2);
|
|
131
|
+
if (point < glibc231PrintableRanges[middle * 2])
|
|
132
|
+
high = middle;
|
|
133
|
+
else if (point > glibc231PrintableRanges[middle * 2 + 1])
|
|
134
|
+
low = middle + 1;
|
|
135
|
+
else {
|
|
136
|
+
printable = true;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const unit = text.slice(offset, offset + length);
|
|
142
|
+
const shellSpecial = '!"$&()*;<=>?[\\^`|'.includes(unit);
|
|
143
|
+
const positional = "#~".includes(unit) ? offset === 0 : "{}".includes(unit) && text.length === 1;
|
|
144
|
+
units.push({ text: unit, printable, shellSpecial: shellSpecial || positional,
|
|
145
|
+
cAndShellCompatible: printable && !shellSpecial && (!"#~{}".includes(unit) || positional) });
|
|
146
|
+
offset += length;
|
|
147
|
+
}
|
|
148
|
+
if (filename && text.includes("'") && units.every(unit => unit.cAndShellCompatible))
|
|
149
|
+
return `"${text}"`;
|
|
150
|
+
const left = !filename && unicode ? "\xe2\x80\x98" : "'";
|
|
151
|
+
const right = !filename && unicode ? "\xe2\x80\x99" : "'";
|
|
152
|
+
let result = left;
|
|
153
|
+
let escaping = filename && text.includes("'") && units.length > 0 && !units[units.length - 1].printable;
|
|
154
|
+
for (const unit of units) {
|
|
155
|
+
if (filename && unit.text === "'") {
|
|
156
|
+
result += "'\\''";
|
|
157
|
+
escaping = false;
|
|
158
|
+
}
|
|
159
|
+
else if (!unit.printable) {
|
|
160
|
+
if (filename && !escaping)
|
|
161
|
+
result += "'$'";
|
|
162
|
+
escaping = true;
|
|
163
|
+
result += controls[unit.text] ?? Array.from(unit.text, character => `\\${character.charCodeAt(0).toString(8).padStart(3, "0")}`).join("");
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
if (filename && escaping)
|
|
167
|
+
result += "''";
|
|
168
|
+
escaping = false;
|
|
169
|
+
if (!filename && (unit.text === right || unit.text === "\\"))
|
|
170
|
+
result += "\\";
|
|
171
|
+
result += unit.text;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return result + right;
|
|
175
|
+
}
|
|
176
|
+
function number(text, unicode) {
|
|
177
|
+
let offset = 0;
|
|
178
|
+
const negative = text[0] === "-";
|
|
179
|
+
if (negative || text[0] === "+")
|
|
180
|
+
offset++;
|
|
181
|
+
const start = offset;
|
|
182
|
+
let value = 0n;
|
|
183
|
+
while (text.charCodeAt(offset) >= 48 && text.charCodeAt(offset) <= 57) {
|
|
184
|
+
value = value > -signedMinimum ? -signedMinimum + 1n : value * 10n + BigInt(text.charCodeAt(offset) - 48);
|
|
185
|
+
offset++;
|
|
186
|
+
}
|
|
187
|
+
const powers = { E: 6, g: 3, G: 3, k: 1, K: 1, m: 2, M: 2, P: 5, t: 4, T: 4, Y: 8, Z: 7 };
|
|
188
|
+
let invalid = false;
|
|
189
|
+
if (offset === start) {
|
|
190
|
+
if (offset === 0 && Object.hasOwn(powers, text[0] ?? ""))
|
|
191
|
+
value = 1n;
|
|
192
|
+
else
|
|
193
|
+
invalid = true;
|
|
194
|
+
}
|
|
195
|
+
if (negative)
|
|
196
|
+
value = -value;
|
|
197
|
+
let overflow = value < signedMinimum || value > signedMaximum;
|
|
198
|
+
if (offset < text.length) {
|
|
199
|
+
const power = powers[text[offset]];
|
|
200
|
+
if (power === undefined)
|
|
201
|
+
invalid = true;
|
|
202
|
+
else {
|
|
203
|
+
offset++;
|
|
204
|
+
let base = 1024n;
|
|
205
|
+
if (text.slice(offset, offset + 2) === "iB")
|
|
206
|
+
offset += 2;
|
|
207
|
+
else if (text[offset] === "B" || text[offset] === "D") {
|
|
208
|
+
base = 1000n;
|
|
209
|
+
offset++;
|
|
210
|
+
}
|
|
211
|
+
value *= base ** BigInt(power);
|
|
212
|
+
overflow ||= value < signedMinimum || value > signedMaximum;
|
|
213
|
+
invalid ||= offset !== text.length;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (invalid || overflow)
|
|
217
|
+
throw new TruncateDiagnostic(`Invalid number: ${quote(text, false, unicode)}${overflow && !invalid ? ": Value too large for defined data type" : ""}`);
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
function parse(context, argumentLimit) {
|
|
221
|
+
if (context.args.length > 4096)
|
|
222
|
+
throw new PublicDiagnostic("argument limit exceeded");
|
|
223
|
+
let total = 0;
|
|
224
|
+
for (const argument of context.args) {
|
|
225
|
+
if (context.argumentValues !== undefined) {
|
|
226
|
+
total += argument.length;
|
|
227
|
+
if (total > argumentLimit)
|
|
228
|
+
throw new PublicDiagnostic("argument limit exceeded");
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
for (const character of argument) {
|
|
232
|
+
const point = character.codePointAt(0);
|
|
233
|
+
total += point < 128 ? 1 : point < 2048 ? 2 : point < 65536 ? 3 : 4;
|
|
234
|
+
if (total > argumentLimit)
|
|
235
|
+
throw new PublicDiagnostic("argument limit exceeded");
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
const carrier = getCommandArguments(context);
|
|
239
|
+
total = 0;
|
|
240
|
+
for (const value of carrier.values) {
|
|
241
|
+
total += shellValueByteLength(value);
|
|
242
|
+
if (total > argumentLimit)
|
|
243
|
+
throw new PublicDiagnostic("argument limit exceeded");
|
|
244
|
+
}
|
|
245
|
+
const args = context.args.map((_argument, index) => Array.from(carrier.bytes(index), byte => String.fromCharCode(byte)).join(""));
|
|
246
|
+
const settings = { modifier: "absolute", blocks: false, noCreate: false, operands: [] };
|
|
247
|
+
const unicode = unicodeLocale(context);
|
|
248
|
+
const long = { "no-create": "c", "io-blocks": "o", reference: "r", size: "s", help: "help", version: "version" };
|
|
249
|
+
const apply = (key, value = "") => {
|
|
250
|
+
if (key === "c")
|
|
251
|
+
settings.noCreate = true;
|
|
252
|
+
else if (key === "o")
|
|
253
|
+
settings.blocks = true;
|
|
254
|
+
else if (key === "r")
|
|
255
|
+
settings.reference = value;
|
|
256
|
+
else if (key === "help" || key === "version")
|
|
257
|
+
settings.information = key;
|
|
258
|
+
else {
|
|
259
|
+
let offset = 0;
|
|
260
|
+
while (value.charCodeAt(offset) === 32 || value.charCodeAt(offset) >= 9 && value.charCodeAt(offset) <= 13)
|
|
261
|
+
offset++;
|
|
262
|
+
const modifiers = { "<": "maximum", ">": "minimum", "/": "down", "%": "up" };
|
|
263
|
+
if (Object.hasOwn(modifiers, value[offset] ?? ""))
|
|
264
|
+
settings.modifier = modifiers[value[offset++]];
|
|
265
|
+
while (value.charCodeAt(offset) === 32 || value.charCodeAt(offset) >= 9 && value.charCodeAt(offset) <= 13)
|
|
266
|
+
offset++;
|
|
267
|
+
if (value[offset] === "+" || value[offset] === "-") {
|
|
268
|
+
if (settings.modifier !== "absolute")
|
|
269
|
+
throw new TruncateDiagnostic("multiple relative modifiers specified", true);
|
|
270
|
+
settings.modifier = "relative";
|
|
271
|
+
}
|
|
272
|
+
settings.size = number(value.slice(offset), unicode);
|
|
273
|
+
if ((settings.modifier === "down" || settings.modifier === "up") && settings.size === 0n)
|
|
274
|
+
throw new TruncateDiagnostic("division by zero");
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
let stopped = false;
|
|
278
|
+
for (let index = 0; index < args.length; index++) {
|
|
279
|
+
const argument = args[index];
|
|
280
|
+
if (stopped || argument === "-" || !argument.startsWith("-")) {
|
|
281
|
+
settings.operands.push(argument);
|
|
282
|
+
if (context.env.POSIXLY_CORRECT !== undefined)
|
|
283
|
+
stopped = true;
|
|
284
|
+
}
|
|
285
|
+
else if (argument === "--")
|
|
286
|
+
stopped = true;
|
|
287
|
+
else if (argument.startsWith("--")) {
|
|
288
|
+
const equals = argument.indexOf("=");
|
|
289
|
+
const name = argument.slice(2, equals < 0 ? undefined : equals);
|
|
290
|
+
const matches = Object.keys(long).filter(candidate => candidate.startsWith(name));
|
|
291
|
+
const selected = Object.hasOwn(long, name) ? name : matches.length === 1 ? matches[0] : undefined;
|
|
292
|
+
if (!selected)
|
|
293
|
+
throw new TruncateDiagnostic(matches.length > 1 ? `option '${argument}' is ambiguous; possibilities: ${matches.map(candidate => `'--${candidate}'`).join(" ")}` : `unrecognized option '${argument}'`, true);
|
|
294
|
+
const key = long[selected];
|
|
295
|
+
const required = key === "s" || key === "r";
|
|
296
|
+
if (!required && equals >= 0)
|
|
297
|
+
throw new TruncateDiagnostic(`option '--${selected}' doesn't allow an argument`, true);
|
|
298
|
+
const value = required ? equals < 0 ? args[++index] : argument.slice(equals + 1) : "";
|
|
299
|
+
if (value === undefined)
|
|
300
|
+
throw new TruncateDiagnostic(`option '--${selected}' requires an argument`, true);
|
|
301
|
+
apply(key, value);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
for (let position = 1; position < argument.length; position++) {
|
|
305
|
+
const key = argument[position];
|
|
306
|
+
if (!"cors".includes(key))
|
|
307
|
+
throw new TruncateDiagnostic(`invalid option -- '${key}'`, true);
|
|
308
|
+
let value = "";
|
|
309
|
+
if (key === "r" || key === "s") {
|
|
310
|
+
const supplied = argument.slice(position + 1) || args[++index];
|
|
311
|
+
if (supplied === undefined)
|
|
312
|
+
throw new TruncateDiagnostic(`option requires an argument -- '${key}'`, true);
|
|
313
|
+
value = supplied;
|
|
314
|
+
position = argument.length;
|
|
315
|
+
}
|
|
316
|
+
apply(key, value);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (settings.information)
|
|
320
|
+
return settings;
|
|
321
|
+
}
|
|
322
|
+
if (settings.reference === undefined && settings.size === undefined)
|
|
323
|
+
throw new TruncateDiagnostic(`you must specify either ${quote("--size", false, unicode)} or ${quote("--reference", false, unicode)}`, true);
|
|
324
|
+
if (settings.reference !== undefined && settings.size !== undefined && settings.modifier === "absolute")
|
|
325
|
+
throw new TruncateDiagnostic(`you must specify a relative ${quote("--size", false, unicode)} with ${quote("--reference", false, unicode)}`, true);
|
|
326
|
+
if (settings.blocks && settings.size === undefined)
|
|
327
|
+
throw new TruncateDiagnostic(`${quote("--io-blocks", false, unicode)} was specified but ${quote("--size", false, unicode)} was not`, true);
|
|
328
|
+
if (!settings.operands.length)
|
|
329
|
+
throw new TruncateDiagnostic("missing file operand", true);
|
|
330
|
+
return settings;
|
|
331
|
+
}
|
|
332
|
+
function filePath(context, name) {
|
|
333
|
+
let decoded;
|
|
334
|
+
try {
|
|
335
|
+
decoded = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(name, character => character.charCodeAt(0)));
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
throw new FsError("ENOENT");
|
|
339
|
+
}
|
|
340
|
+
return pathOf(context, decoded);
|
|
341
|
+
}
|
|
342
|
+
function ioError(error, label) {
|
|
343
|
+
if (!(error instanceof FsError))
|
|
344
|
+
return error;
|
|
345
|
+
const descriptions = {
|
|
346
|
+
ENOENT: "No such file or directory", EACCES: "Permission denied", EPERM: "Operation not permitted", EISDIR: "Is a directory",
|
|
347
|
+
ENOTDIR: "Not a directory", EBADF: "Bad file descriptor", EIO: "Input/output error", ENOSPC: "No space left on device",
|
|
348
|
+
EPIPE: "Broken pipe", ESPIPE: "Illegal seek", ELOOP: "Too many levels of symbolic links", ENAMETOOLONG: "File name too long", ENOTSUP: "Operation not supported",
|
|
349
|
+
EFBIG: "File too large", EINVAL: "Invalid argument", EROFS: "Read-only file system", EMFILE: "Too many open files",
|
|
350
|
+
};
|
|
351
|
+
return descriptions[error.code] ? new TruncateDiagnostic(`${label}: ${descriptions[error.code]}`) : error;
|
|
352
|
+
}
|
|
353
|
+
function interrupt(pending, signal) {
|
|
354
|
+
return new Promise((resolve, reject) => {
|
|
355
|
+
const abort = () => { signal.removeEventListener("abort", abort); reject(signal.reason); };
|
|
356
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
357
|
+
pending.then(value => { signal.removeEventListener("abort", abort); resolve(value); }, error => { signal.removeEventListener("abort", abort); reject(error); });
|
|
358
|
+
if (signal.aborted)
|
|
359
|
+
abort();
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
function observedSize(stat, label) {
|
|
363
|
+
if (stat.type !== "file")
|
|
364
|
+
throw new TruncateDiagnostic(`cannot get the size of ${label}: Operation not supported`);
|
|
365
|
+
if (!Number.isSafeInteger(stat.size))
|
|
366
|
+
throw new PublicDiagnostic("file size is not a safe integer");
|
|
367
|
+
if (stat.size < 0)
|
|
368
|
+
throw new TruncateDiagnostic(`${label} has unusable, apparently negative size`);
|
|
369
|
+
return BigInt(stat.size);
|
|
370
|
+
}
|
|
371
|
+
export function truncateCommand(options = {}) {
|
|
372
|
+
const configured = metadataSettings(options);
|
|
373
|
+
const argumentLimit = Math.min(65536, configured.limits.maxArgumentBytes);
|
|
374
|
+
const outputMaximum = Math.min(bufferLimit, configured.limits.maxOutputBytes);
|
|
375
|
+
return { name: "truncate", filesystemRequirements: [{ id: "resize", description: "Resize retained writable VFS entries", capabilities: ["retainedResize"], mutates: true }], async execute(context) {
|
|
376
|
+
context.signal.throwIfAborted();
|
|
377
|
+
const root = createOutputOperation({ signal: context.signal, registerCleanup(cleanup) {
|
|
378
|
+
let retirement;
|
|
379
|
+
context.registerCleanup?.(() => retirement ??= Promise.resolve(cleanup()).catch(() => { }));
|
|
380
|
+
} }, { async write() { throw new Error("resource scope has no output destination"); } });
|
|
381
|
+
const signal = root.signal;
|
|
382
|
+
const stdout = root.child(context.stdout), stderr = root.child(context.stderr);
|
|
383
|
+
const closures = new WeakMap();
|
|
384
|
+
const active = new WeakMap();
|
|
385
|
+
const closeHandle = (handle) => {
|
|
386
|
+
let closing = closures.get(handle);
|
|
387
|
+
if (!closing) {
|
|
388
|
+
closing = Promise.resolve().then(async () => { await active.get(handle); await handle.close(); });
|
|
389
|
+
closures.set(handle, closing);
|
|
390
|
+
}
|
|
391
|
+
return closing;
|
|
392
|
+
};
|
|
393
|
+
const closeReference = async (handle) => {
|
|
394
|
+
try {
|
|
395
|
+
await closeHandle(handle);
|
|
396
|
+
}
|
|
397
|
+
catch { }
|
|
398
|
+
};
|
|
399
|
+
const useHandle = (handle, start) => root.acquire(signal => {
|
|
400
|
+
let finish;
|
|
401
|
+
active.set(handle, new Promise(resolve => { finish = resolve; }));
|
|
402
|
+
try {
|
|
403
|
+
return Promise.resolve(start(signal)).finally(finish);
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
finish();
|
|
407
|
+
throw error;
|
|
408
|
+
}
|
|
409
|
+
}, () => { });
|
|
410
|
+
const seekSize = async (handle, label) => {
|
|
411
|
+
try {
|
|
412
|
+
const end = await useHandle(handle, signal => {
|
|
413
|
+
const seekEnd = handle.seekEnd;
|
|
414
|
+
signal.throwIfAborted();
|
|
415
|
+
if (typeof seekEnd !== "function")
|
|
416
|
+
throw new FsError("ENOTSUP");
|
|
417
|
+
return Reflect.apply(seekEnd, handle, [{ signal }]);
|
|
418
|
+
});
|
|
419
|
+
if (typeof end !== "bigint" || end < 0n || end > signedMaximum)
|
|
420
|
+
throw new PublicDiagnostic("invalid retained end-seek offset");
|
|
421
|
+
return end;
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
signal.throwIfAborted();
|
|
425
|
+
throw ioError(error, `cannot get the size of ${label}`);
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
let outputBytes = 0;
|
|
429
|
+
const outputLimit = new PublicDiagnostic("truncate output limit exceeded");
|
|
430
|
+
const emit = async (text, error = true, utf8 = false) => {
|
|
431
|
+
const used = outputBytes;
|
|
432
|
+
if (text.length > outputMaximum - used)
|
|
433
|
+
throw outputLimit;
|
|
434
|
+
let length = text.length;
|
|
435
|
+
if (utf8) {
|
|
436
|
+
length = 0;
|
|
437
|
+
let scanned = 0;
|
|
438
|
+
for (const character of text) {
|
|
439
|
+
if (++scanned % 65536 === 0)
|
|
440
|
+
await yieldTurn(signal);
|
|
441
|
+
const point = character.codePointAt(0);
|
|
442
|
+
length += point < 128 ? 1 : point < 2048 ? 2 : point < 65536 ? 3 : 4;
|
|
443
|
+
if (length > outputMaximum - used)
|
|
444
|
+
throw outputLimit;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
outputBytes += length;
|
|
448
|
+
const encoder = new TextEncoder();
|
|
449
|
+
for (let offset = 0; offset < text.length;) {
|
|
450
|
+
let end = Math.min(text.length, offset + (utf8 ? 16384 : 65536));
|
|
451
|
+
if (utf8 && end < text.length && text.charCodeAt(end - 1) >= 0xd800 && text.charCodeAt(end - 1) <= 0xdbff)
|
|
452
|
+
end--;
|
|
453
|
+
const chunk = text.slice(offset, end);
|
|
454
|
+
await writeBytes(error ? stderr.output : stdout.output, utf8 ? encoder.encode(chunk) : Uint8Array.from(chunk, character => character.charCodeAt(0)), signal);
|
|
455
|
+
offset = end;
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
const report = async (error) => {
|
|
459
|
+
signal.throwIfAborted();
|
|
460
|
+
if (!(error instanceof TruncateDiagnostic))
|
|
461
|
+
throw error;
|
|
462
|
+
await emit(`truncate: ${error.detail}\n${error.usage ? "Try 'truncate --help' for more information.\n" : ""}`);
|
|
463
|
+
};
|
|
464
|
+
let outcome;
|
|
465
|
+
try {
|
|
466
|
+
const settings = parse(context, argumentLimit);
|
|
467
|
+
const unicode = unicodeLocale(context);
|
|
468
|
+
if (settings.information) {
|
|
469
|
+
await emit(settings.information === "help" ? helpText : "truncate (virtual-bash)\n", false);
|
|
470
|
+
outcome = { exitCode: 0 };
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
let reference;
|
|
474
|
+
if (settings.reference !== undefined) {
|
|
475
|
+
const label = quote(settings.reference, true, unicode);
|
|
476
|
+
let stat;
|
|
477
|
+
try {
|
|
478
|
+
const filesystem = context.fs;
|
|
479
|
+
const path = filePath(context, settings.reference);
|
|
480
|
+
const referenceStat = filesystem.stat;
|
|
481
|
+
signal.throwIfAborted();
|
|
482
|
+
stat = await interrupt(Promise.resolve(Reflect.apply(referenceStat, filesystem, [path, { signal }])), signal);
|
|
483
|
+
}
|
|
484
|
+
catch (error) {
|
|
485
|
+
signal.throwIfAborted();
|
|
486
|
+
throw ioError(error, `cannot stat ${label}`);
|
|
487
|
+
}
|
|
488
|
+
if (stat.type === "file")
|
|
489
|
+
reference = observedSize(stat, label);
|
|
490
|
+
else {
|
|
491
|
+
let handle;
|
|
492
|
+
try {
|
|
493
|
+
const filesystem = context.fs;
|
|
494
|
+
const path = filePath(context, settings.reference);
|
|
495
|
+
const capabilitiesFor = filesystem.capabilitiesFor;
|
|
496
|
+
signal.throwIfAborted();
|
|
497
|
+
const capabilities = await interrupt(Promise.resolve((capabilitiesFor == null ? undefined : Reflect.apply(capabilitiesFor, filesystem, [path, { allowDirectory: true, signal }])) ?? filesystem.capabilities), signal);
|
|
498
|
+
signal.throwIfAborted();
|
|
499
|
+
const retainedRead = capabilities.retainedRead;
|
|
500
|
+
signal.throwIfAborted();
|
|
501
|
+
if (retainedRead !== true)
|
|
502
|
+
throw new FsError("ENOTSUP");
|
|
503
|
+
const openReadFile = filesystem.openReadFile;
|
|
504
|
+
signal.throwIfAborted();
|
|
505
|
+
if (typeof openReadFile !== "function")
|
|
506
|
+
throw new FsError("ENOTSUP");
|
|
507
|
+
handle = await root.acquire(signal => Reflect.apply(openReadFile, filesystem, [path, { allowDirectory: true, signal }]), closeReference);
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
signal.throwIfAborted();
|
|
511
|
+
throw ioError(error, `cannot get the size of ${label}`);
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
reference = await seekSize(handle, label);
|
|
515
|
+
}
|
|
516
|
+
finally {
|
|
517
|
+
await closeReference(handle);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
let exitCode = 0;
|
|
522
|
+
for (let index = 0; index < settings.operands.length; index++) {
|
|
523
|
+
if (index % 64 === 0)
|
|
524
|
+
await yieldTurn(signal);
|
|
525
|
+
signal.throwIfAborted();
|
|
526
|
+
if (index >= configured.limits.maxEntries)
|
|
527
|
+
throw new PublicDiagnostic("entry limit exceeded");
|
|
528
|
+
const name = settings.operands[index];
|
|
529
|
+
const label = quote(name, true, unicode);
|
|
530
|
+
let handle;
|
|
531
|
+
try {
|
|
532
|
+
const path = filePath(context, name);
|
|
533
|
+
const filesystem = context.fs;
|
|
534
|
+
const capabilitiesFor = filesystem.capabilitiesFor;
|
|
535
|
+
signal.throwIfAborted();
|
|
536
|
+
const capabilities = await interrupt(Promise.resolve((capabilitiesFor == null ? undefined : Reflect.apply(capabilitiesFor, filesystem, [path, { create: !settings.noCreate, signal }])) ?? filesystem.capabilities), signal);
|
|
537
|
+
signal.throwIfAborted();
|
|
538
|
+
const readOnly = capabilities.readOnly;
|
|
539
|
+
signal.throwIfAborted();
|
|
540
|
+
if (readOnly === true)
|
|
541
|
+
throw new FsError("EROFS");
|
|
542
|
+
const retainedResize = capabilities.retainedResize;
|
|
543
|
+
signal.throwIfAborted();
|
|
544
|
+
if (retainedResize !== true)
|
|
545
|
+
throw new FsError("ENOTSUP");
|
|
546
|
+
const openResizeFile = filesystem.openResizeFile;
|
|
547
|
+
signal.throwIfAborted();
|
|
548
|
+
if (typeof openResizeFile !== "function")
|
|
549
|
+
throw new FsError("ENOTSUP");
|
|
550
|
+
handle = await root.acquire(signal => Reflect.apply(openResizeFile, filesystem, [path, { create: !settings.noCreate, mode: 0o666 & ~configured.umask, signal }]), closeHandle);
|
|
551
|
+
}
|
|
552
|
+
catch (error) {
|
|
553
|
+
signal.throwIfAborted();
|
|
554
|
+
if (settings.noCreate && error instanceof FsError && error.code === "ENOENT")
|
|
555
|
+
continue;
|
|
556
|
+
await report(ioError(error, `cannot open ${label} for writing`));
|
|
557
|
+
exitCode = 1;
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
try {
|
|
561
|
+
let size = settings.size ?? reference;
|
|
562
|
+
let stat;
|
|
563
|
+
if (settings.blocks || settings.modifier !== "absolute" && reference === undefined) {
|
|
564
|
+
try {
|
|
565
|
+
stat = await useHandle(handle, signal => {
|
|
566
|
+
const stat = handle.stat;
|
|
567
|
+
signal.throwIfAborted();
|
|
568
|
+
return Reflect.apply(stat, handle, [{ signal }]);
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
catch (error) {
|
|
572
|
+
signal.throwIfAborted();
|
|
573
|
+
throw ioError(error, `cannot fstat ${label}`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
if (settings.blocks) {
|
|
577
|
+
const hint = stat.preferredIoBlockSize;
|
|
578
|
+
if (hint === undefined || !Number.isSafeInteger(hint) || hint <= 0)
|
|
579
|
+
throw new TruncateDiagnostic(`cannot get the I/O block size of ${label}: Operation not supported`);
|
|
580
|
+
const block = BigInt(hint);
|
|
581
|
+
if (size < signedMinimum / block || size > signedMaximum / block)
|
|
582
|
+
throw new TruncateDiagnostic(`overflow in ${size} * ${block} byte blocks for file ${label}`);
|
|
583
|
+
size *= block;
|
|
584
|
+
}
|
|
585
|
+
if (settings.modifier !== "absolute") {
|
|
586
|
+
const base = reference ?? (stat.type === "file" ? observedSize(stat, label) : await seekSize(handle, label));
|
|
587
|
+
if (settings.modifier === "minimum")
|
|
588
|
+
size = base > size ? base : size;
|
|
589
|
+
else if (settings.modifier === "maximum")
|
|
590
|
+
size = base < size ? base : size;
|
|
591
|
+
else if (settings.modifier === "down")
|
|
592
|
+
size = base / size * size;
|
|
593
|
+
else if (settings.modifier === "up") {
|
|
594
|
+
size = (base + size - 1n) / size * size;
|
|
595
|
+
if (size > signedMaximum)
|
|
596
|
+
throw new TruncateDiagnostic(`overflow rounding up size of file ${label}`);
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
if (size > signedMaximum - base)
|
|
600
|
+
throw new TruncateDiagnostic(`overflow extending size of file ${label}`);
|
|
601
|
+
size += base;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (size < 0n)
|
|
605
|
+
size = 0n;
|
|
606
|
+
try {
|
|
607
|
+
if (size > BigInt(Number.MAX_SAFE_INTEGER))
|
|
608
|
+
throw new FsError("EFBIG");
|
|
609
|
+
await useHandle(handle, signal => {
|
|
610
|
+
const truncate = handle.truncate;
|
|
611
|
+
signal.throwIfAborted();
|
|
612
|
+
return Reflect.apply(truncate, handle, [Number(size), { signal }]);
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
catch (error) {
|
|
616
|
+
signal.throwIfAborted();
|
|
617
|
+
throw ioError(error, `failed to truncate ${label} at ${size} bytes`);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
catch (error) {
|
|
621
|
+
await report(error);
|
|
622
|
+
exitCode = 1;
|
|
623
|
+
}
|
|
624
|
+
try {
|
|
625
|
+
await closeHandle(handle);
|
|
626
|
+
}
|
|
627
|
+
catch (error) {
|
|
628
|
+
await report(ioError(error, `failed to close ${label}`));
|
|
629
|
+
exitCode = 1;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
outcome = { exitCode };
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
catch (error) {
|
|
636
|
+
try {
|
|
637
|
+
signal.throwIfAborted();
|
|
638
|
+
if (error === outputLimit)
|
|
639
|
+
outcome = { exitCode: 1 };
|
|
640
|
+
else if (error instanceof TruncateDiagnostic) {
|
|
641
|
+
await report(error);
|
|
642
|
+
outcome = { exitCode: 1 };
|
|
643
|
+
}
|
|
644
|
+
else if (error instanceof PublicDiagnostic) {
|
|
645
|
+
await emit(`truncate: ${publicDiagnosticMessage(error, context.onInternalError)}\n`, true, true);
|
|
646
|
+
outcome = { exitCode: 1 };
|
|
647
|
+
}
|
|
648
|
+
else
|
|
649
|
+
outcome = { error };
|
|
650
|
+
}
|
|
651
|
+
catch (failure) {
|
|
652
|
+
outcome = failure === outputLimit ? { exitCode: 1 } : { error: failure };
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
try {
|
|
656
|
+
await root.close();
|
|
657
|
+
}
|
|
658
|
+
catch (error) {
|
|
659
|
+
if (!("error" in outcome) && outcome.exitCode === 0)
|
|
660
|
+
outcome = { error };
|
|
661
|
+
}
|
|
662
|
+
context.signal.throwIfAborted();
|
|
663
|
+
if ("error" in outcome)
|
|
664
|
+
throw outcome.error;
|
|
665
|
+
return outcome;
|
|
666
|
+
} };
|
|
667
|
+
}
|
|
668
|
+
//# sourceMappingURL=truncate.js.map
|