Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4f8493ffe | ||
|
|
687eaa0eb5 | ||
|
|
011d93c524 | ||
|
|
97f0f5726c | ||
|
|
9c546dfd05 | ||
|
|
8941548ddc | ||
|
|
179d480020 | ||
|
|
4092a164d8 | ||
|
|
ca7c29ab8d | ||
|
|
e4a9a3621f | ||
|
|
f1b7d5ddbe | ||
|
|
78fae360f7 | ||
|
|
cb29deed54 | ||
|
|
390cf01ce1 | ||
|
|
7387b80843 | ||
|
|
c6b71ecfe1 | ||
|
|
1422edeb6a | ||
|
|
7c57fb08ad | ||
|
|
88a304dc16 | ||
|
|
411808c680 | ||
|
|
1fbd9b56a3 | ||
|
|
bbfc794852 | ||
|
|
65edd8ff3a | ||
|
|
5e8d201571 | ||
|
|
7523111d67 | ||
|
|
d4a0d4ffdd | ||
|
|
aeecd914cf | ||
|
|
1190e70085 | ||
|
|
34ee909c59 | ||
|
|
ed14b56a7c | ||
|
|
ca7829b996 | ||
|
|
1c99a3820b | ||
|
|
9258cee615 | ||
|
|
c427c367c1 | ||
|
|
f58ad83c95 | ||
|
|
05f9adade5 | ||
|
|
b29da37462 | ||
|
|
827614dd66 | ||
|
|
d075ddf1ed | ||
|
|
5971d622bd | ||
|
|
14ee298bc3 | ||
|
|
07c1798b5e | ||
|
|
4765b677e7 | ||
|
|
9dbec3cf50 | ||
|
|
246d7701e4 | ||
|
|
8f4bed3274 | ||
|
|
7e993ba14e | ||
|
|
ae0fe82d8a | ||
|
|
76a8da7dc1 | ||
|
|
6130d65249 | ||
|
|
85918358a5 | ||
|
|
0331673e02 | ||
|
|
542c91cdbc | ||
|
|
868a054366 | ||
|
|
549db120db | ||
|
|
0a1e53c2db | ||
|
|
ecfe1f72e3 | ||
|
|
703cf06b7e | ||
|
|
3628ed5072 | ||
|
|
067c9aa7a3 | ||
|
|
9b3f37c233 | ||
|
|
b20598ff72 | ||
|
|
8bd5e89f92 | ||
|
|
905894f294 | ||
|
|
453bcec11a | ||
|
|
a984ab5dd3 | ||
|
|
624097639f | ||
|
|
47ca0d8cf8 | ||
|
|
5944115d94 | ||
|
|
b99026d7d7 | ||
|
|
f72486d4e8 | ||
|
|
e74cab6985 | ||
|
|
a0a097decb | ||
|
|
d0b230bceb | ||
|
|
63f4a0bc39 | ||
|
|
983f75c7df | ||
|
|
e043efd259 | ||
|
|
7e99aa5b13 | ||
|
|
2d08b3208a | ||
|
|
944ae9aca1 | ||
|
|
e82d5e48f4 | ||
|
|
98c92e0239 | ||
|
|
6c5d86c66f | ||
|
|
9d96c7d6eb | ||
|
|
1f27ba3b35 | ||
|
|
4aa73d5fc6 | ||
|
|
50150d0d66 | ||
|
|
192566a9fd | ||
|
|
6dcb41f2fa | ||
|
|
54b0c8bc23 | ||
|
|
6609500d90 | ||
|
|
905e27ad47 | ||
|
|
df77b78e23 | ||
|
|
87f2326012 | ||
|
|
a0cd6a5d18 | ||
|
|
e11d1dec19 | ||
|
|
b51afc07e2 | ||
|
|
813f6aaeab | ||
|
|
49adee62c4 | ||
|
|
35d1e59f74 | ||
|
|
1a00a7fdf5 | ||
|
|
d546e90a94 | ||
|
|
82de6be6fd | ||
|
|
958cacf4bb | ||
|
|
8198058bb2 | ||
|
|
60203aabf5 | ||
|
|
d65dbd2f37 | ||
|
|
65741d9b2e | ||
|
|
4fbcfebc6c | ||
|
|
270bcb066e | ||
|
|
229aadf194 | ||
|
|
6b0f8477d0 | ||
|
|
61b412b0f1 | ||
|
|
6772d7e5a1 | ||
|
|
f6b2196369 | ||
|
|
d2c183d234 | ||
|
|
e09976042d | ||
|
|
7ddbc72525 | ||
|
|
7c19f58e75 | ||
|
|
723d96b54b | ||
|
|
6b5d217e22 | ||
|
|
d9eb83e1f5 | ||
|
|
411f9529a2 | ||
|
|
adf2767763 | ||
|
|
4fc5d10671 | ||
|
|
19d1835d37 | ||
|
|
6f9e73f058 | ||
|
|
5897576ca1 | ||
|
|
9b28da72eb | ||
|
|
d49234eefe | ||
|
|
4bfe83a445 | ||
|
|
228ff740bf | ||
|
|
c69343856a | ||
|
|
d381a1c714 | ||
|
|
0a98062586 | ||
|
|
e7087b101d | ||
|
|
eae06cf3c0 | ||
|
|
0e7a77b42a | ||
|
|
a78a432f50 | ||
|
|
4867b641a7 | ||
|
|
355d030ce0 | ||
|
|
547efed258 | ||
|
|
a4b90879a0 | ||
|
|
3b1bad2334 | ||
|
|
cfe7b4e97a | ||
|
|
10895792d2 | ||
|
|
6b19d8e31c | ||
|
|
f3ce23e7c7 | ||
|
|
663a54bda0 | ||
|
|
ae60fc0688 | ||
|
|
11d727a88d | ||
|
|
b75ecd79d5 | ||
|
|
5fb7e49848 | ||
|
|
21c8237a73 | ||
|
|
b300046eb1 | ||
|
|
17cbab3045 | ||
|
|
d421024fb8 | ||
|
|
7a6ce0f0b6 | ||
|
|
b1bf99c09b | ||
|
|
096b655bb8 | ||
|
|
7a276040ad | ||
|
|
89d2a7840f | ||
|
|
fb2b325e94 | ||
|
|
e7d188ac65 | ||
|
|
79a6420fea | ||
|
|
c54c3258a6 | ||
|
|
0c28d017de | ||
|
|
0a69501594 | ||
|
|
a3f0caeab4 | ||
|
|
478039f539 | ||
|
|
2a25221eaf | ||
|
|
c763f1fcaa | ||
|
|
8b4fa8ade7 | ||
|
|
57f0b91d16 | ||
|
|
a66a1cc10c | ||
|
|
2a31b73a32 | ||
|
|
ee96f3f43b | ||
|
|
2b1d359281 | ||
|
|
4854d71aa9 | ||
|
|
18b1926d61 | ||
|
|
43a54bd541 | ||
|
|
bf371e9a8c | ||
|
|
239a20d13f | ||
|
|
a220e993af | ||
|
|
a955038360 | ||
|
|
c0e530eefd | ||
|
|
1d28da18ce | ||
|
|
571c3bee06 | ||
|
|
618f1c1578 | ||
|
|
496b1e431e | ||
|
|
ef9240a7a5 | ||
|
|
b2f44b6724 | ||
|
|
c19d16b3c8 | ||
|
|
0440ba26da | ||
|
|
070bcb5acc | ||
|
|
f3353cb4bd | ||
|
|
9f63212a7c | ||
|
|
a59c91f03d | ||
|
|
f724ebe158 | ||
|
|
3bc102c334 | ||
|
|
d638cd50f4 | ||
|
|
ebbcdf4b4d | ||
|
|
b3410cf8c0 | ||
|
|
dc51002ba4 | ||
|
|
9bc5903337 | ||
|
|
26c4ad45bd | ||
|
|
cb8cac81aa | ||
|
|
7dc02a475e | ||
|
|
25f43e129f | ||
|
|
b12681d667 | ||
|
|
0af9cb2314 | ||
|
|
fc364d381f | ||
|
|
0481e99c2f | ||
|
|
7eedf884ea | ||
|
|
ebefc02f4e | ||
|
|
17d9ee59e7 | ||
|
|
fec4253f07 | ||
|
|
505a6d9d2b | ||
|
|
3a90959f9c | ||
|
|
73d1237f1b | ||
|
|
1b5a936ebf | ||
|
|
7de5e2ca33 | ||
|
|
854186c942 | ||
|
|
39c7d4f586 | ||
|
|
2e08bbb20a | ||
|
|
bea21335c0 | ||
|
|
ba80d546bc | ||
|
|
d120d654c6 | ||
|
|
b68560a5b6 | ||
|
|
d66343d6f6 | ||
|
|
7e1aa366b6 | ||
|
|
4749cdbb27 | ||
|
|
70fd445307 | ||
|
|
99d27893eb | ||
|
|
ef730dda06 | ||
|
|
e82aa71f26 | ||
|
|
e0f091384f | ||
|
|
bca6fc9542 | ||
|
|
937298eec2 | ||
|
|
2ff99ab1cd | ||
|
|
593723ba92 | ||
|
|
989a34b7c7 | ||
|
|
49b6c71f42 | ||
|
|
b3eacc71d0 | ||
|
|
0eab393715 | ||
|
|
52585447f0 | ||
|
|
3eff81f1a6 | ||
|
|
72376e2d29 | ||
|
|
7532f33c7d | ||
|
|
cf68a17f33 | ||
|
|
f4a3d61a17 | ||
|
|
e01e456825 | ||
|
|
ba0738496e | ||
|
|
bec0b6924e | ||
|
|
1f96f368bd | ||
|
|
3aac6a7b64 | ||
|
|
fc23d71226 | ||
|
|
c2474f5c33 | ||
|
|
9427d210d8 | ||
|
|
bd5b709dda | ||
|
|
b79273bb91 | ||
|
|
f5fd94ef77 | ||
|
|
7c0573c847 | ||
|
|
02b3f215fc | ||
|
|
00b03fbfea | ||
|
|
74de4e9a01 | ||
|
|
d8cc637b56 | ||
|
|
8f19633dd7 | ||
|
|
6c3a08af2b | ||
|
|
7892e54d7e | ||
|
|
d7327aaf95 | ||
|
|
80358e84f3 | ||
|
|
002780fbaf | ||
|
|
1003bbb121 | ||
|
|
f36ff9b378 | ||
|
|
ad834055db | ||
|
|
7ce6d275ba | ||
|
|
8ef4ff2e84 | ||
|
|
00f06f2b2c | ||
|
|
2a54d4edcc | ||
|
|
8281b918ef | ||
|
|
3c8393f8be | ||
|
|
b1178b2ee2 | ||
|
|
d670d47542 | ||
|
|
00cd3cfcc5 | ||
|
|
7edbd3e951 | ||
|
|
d98237134b | ||
|
|
53d9f81eee | ||
|
|
7e504b2f47 | ||
|
|
0e2e30a74c | ||
|
|
7373ccfaad | ||
|
|
1442c148d8 | ||
|
|
59873f1d41 | ||
|
|
805f66badf | ||
|
|
a063b95005 | ||
|
|
5c84305817 | ||
|
|
c8e13d226b | ||
|
|
6a20139f5c | ||
|
|
7be959ece1 | ||
|
|
b3896f93b2 | ||
|
|
09a55ef62a | ||
|
|
149be3f9ab | ||
|
|
f647b12a2d | ||
|
|
ff8e396500 | ||
|
|
04f99c4951 | ||
|
|
29c65ad9e1 | ||
|
|
f84a668098 | ||
|
|
06721c7be1 | ||
|
|
bd70b0c6cb | ||
|
|
220625f370 | ||
|
|
4606638567 | ||
|
|
882428883a | ||
|
|
c2bbb8eef1 | ||
|
|
111b687449 | ||
|
|
547b52a313 | ||
|
|
5f1893f094 | ||
|
|
a33ee8ef26 | ||
|
|
6d8fbbf848 | ||
|
|
d28d2f3155 | ||
|
|
9566e7d7ea | ||
|
|
c39601bbb2 | ||
|
|
e3fcc6ae71 | ||
|
|
9c18fecb98 | ||
|
|
521391a495 | ||
|
|
f65caacfca | ||
|
|
0a27a85b4a | ||
|
|
d186d618e3 | ||
|
|
ae97565e13 | ||
|
|
d028d5165c | ||
|
|
e17f64fce7 | ||
|
|
e4bc770054 | ||
|
|
a890e8e0c8 | ||
|
|
3af38221ee | ||
|
|
579aebf6a7 | ||
|
|
d91bf78cac | ||
|
|
6e45fe0f8d | ||
|
|
8d7ced4195 | ||
|
|
cae6049edd | ||
|
|
1293f70575 | ||
|
|
ff412009da | ||
|
|
10bc46af6e | ||
|
|
1e5fae3b7b | ||
|
|
a6f72cf985 | ||
|
|
e617b92f2b | ||
|
|
b24771d224 | ||
|
|
6de160192a | ||
|
|
72774e34ff | ||
|
|
4ab9536733 | ||
|
|
bd9af0421c | ||
|
|
7ba474509c | ||
|
|
ac13765fa5 | ||
|
|
ca7997fe7d | ||
|
|
22b729f9ea | ||
|
|
864895f8f2 | ||
|
|
5d185398ac | ||
|
|
94b8b8625f | ||
|
|
282823f660 | ||
|
|
a5fd8d662e | ||
|
|
2904eacefe | ||
|
|
5d538da63a | ||
|
|
fdfceb79c6 | ||
|
|
5aff62414a | ||
|
|
c7a6f85dd2 | ||
|
|
22e9e00f63 | ||
|
|
60ca91209a | ||
|
|
8c440b5417 | ||
|
|
07e6255e7e | ||
|
|
82283ee434 | ||
|
|
42cf7ed628 | ||
|
|
b1cac9b78d | ||
|
|
528889888c | ||
|
|
e6e6ab3b6d | ||
|
|
d2d3ec1cde | ||
|
|
f518257bc9 | ||
|
|
96a411671c | ||
|
|
f07a7b1c87 | ||
|
|
7598b4d46c | ||
|
|
15ed99eee7 | ||
|
|
4df6fbf6f7 | ||
|
|
f125f41428 | ||
|
|
2e9fc77ccd | ||
|
|
590a3535d8 | ||
|
|
b34bba8b4a | ||
|
|
4f82525c39 | ||
|
|
a2191ff270 | ||
|
|
8361ed1fe2 | ||
|
|
9bd96614b3 | ||
|
|
d27672b7a3 | ||
|
|
36d82e313a | ||
|
|
8b3b61e2d3 | ||
|
|
60067ed4ea | ||
|
|
de71cc2389 | ||
|
|
3f1782a573 | ||
|
|
fc379727cc | ||
|
|
0b687edfbe | ||
|
|
546074853e | ||
|
|
7deef78ea5 | ||
|
|
a38e05e749 | ||
|
|
493634e26c | ||
|
|
f96a43e366 | ||
|
|
b434c858a2 | ||
|
|
30e30f0196 | ||
|
|
1a70cc228a | ||
|
|
17ca4fc9c9 | ||
|
|
0aac6d6aac | ||
|
|
61021eab6b | ||
|
|
e59452d765 | ||
|
|
d2647ac55c | ||
|
|
c2c58762f0 | ||
|
|
0a55710cfc | ||
|
|
660d3da704 | ||
|
|
972f8b7df8 | ||
|
|
a40bdfb55f | ||
|
|
3c9ab822fe | ||
|
|
fb5ce33518 | ||
|
|
5c15337662 | ||
|
|
71f929e29c | ||
|
|
c21ad6fdf1 | ||
|
|
f0895177e7 | ||
|
|
72686655cf | ||
|
|
2efe598855 | ||
|
|
54913fddbe | ||
|
|
023cf22a59 | ||
|
|
164d7f7738 | ||
|
|
6b8acd9e01 | ||
|
|
3f6dc99aa5 | ||
|
|
d939d45c27 | ||
|
|
fc8326a2b4 | ||
|
|
8d939c9b99 | ||
|
|
72d9efc993 | ||
|
|
64c4e8efb9 | ||
|
|
25dadb2bfd | ||
|
|
80b68a73ee | ||
|
|
3437b75256 | ||
|
|
462415a88a | ||
|
|
d23a7e929e | ||
|
|
f18fa637c6 | ||
|
|
9bff7f0bb5 | ||
|
|
771b61db30 | ||
|
|
615c1d5321 | ||
|
|
3442d7651a | ||
|
|
7982badb65 | ||
|
|
a83a549de5 | ||
|
|
b1797c51e6 | ||
|
|
8504964f1a | ||
|
|
f83aa2272b | ||
|
|
fb7c05c262 | ||
|
|
e6f611f4de | ||
|
|
bd4ca7301c | ||
|
|
242297a3c6 | ||
|
|
0a658f99bb | ||
|
|
8df1c29c37 | ||
|
|
a8b7cd19bd | ||
|
|
b4f525fd79 | ||
|
|
8caa977a35 | ||
|
|
f6d398738e | ||
|
|
11dc25966d | ||
|
|
efc8b33e81 | ||
|
|
be066f6c8c | ||
|
|
6a1ad7d374 | ||
|
|
751263376b | ||
|
|
d903a7d188 | ||
|
|
a4e2243102 | ||
|
|
9fe604df1a | ||
|
|
64cd9cd85c | ||
|
|
10ef5a8596 | ||
|
|
77ed2e5989 | ||
|
|
8ae549c47f | ||
|
|
284ceba52b | ||
|
|
3ea19829d7 | ||
|
|
c49fc4aa57 | ||
|
|
7fdb6716e1 | ||
|
|
c61c589378 | ||
|
|
c688987087 | ||
|
|
0b2f9ec397 | ||
|
|
8a8e6d71a4 | ||
|
|
a0a9d682ca | ||
|
|
05a72bf75e | ||
|
|
22bf08f8e4 | ||
|
|
b5fbd1978e | ||
|
|
db80f838ff | ||
|
|
8c2e934768 | ||
|
|
dbce5b355e | ||
|
|
12cc996d32 | ||
|
|
4a0f9e713c | ||
|
|
8771b901d9 | ||
|
|
48ac509af7 | ||
|
|
f70627c031 | ||
|
|
1e6c9704b1 | ||
|
|
a629a488d7 | ||
|
|
ad1d0e1c9a | ||
|
|
4f9d746823 | ||
|
|
9fc9b6a8ed | ||
|
|
9ab82cde1e | ||
|
|
a7f392e3c3 | ||
|
|
574ea04502 | ||
|
|
5282a521b5 | ||
|
|
52634f01f9 | ||
|
|
a0f2d9c9c7 | ||
|
|
8386c05978 | ||
|
|
6a2b9a2788 | ||
|
|
e04f50f0dc | ||
|
|
021dc6e054 | ||
|
|
7d7efac7c6 | ||
|
|
f79bed3cb8 | ||
|
|
2171f40703 | ||
|
|
960ff1572f | ||
|
|
da2a2e6fd2 | ||
|
|
005bc2f841 | ||
|
|
ecc0c0e414 | ||
|
|
18548d217b | ||
|
|
653326ca9b | ||
|
|
0cf8902d9b | ||
|
|
762676f4e1 | ||
|
|
3bd49a0c3f | ||
|
|
870dfad9fd | ||
|
|
3b0891b128 | ||
|
|
b3c854b27a | ||
|
|
a923bdaca4 | ||
|
|
0070a74390 | ||
|
|
283bafa228 | ||
|
|
03bd428345 | ||
|
|
f77b853f3f | ||
|
|
43a89a5c61 | ||
|
|
44d7f94c31 | ||
|
|
7c84dc9890 | ||
|
|
025577a13f | ||
|
|
c180cc85cf | ||
|
|
092a30dd7d | ||
|
|
cd7c8f7849 | ||
|
|
89ee1332fe | ||
|
|
b926fffe80 | ||
|
|
7924a796ea | ||
|
|
8d45738126 | ||
|
|
e687c9b4d9 | ||
|
|
d2e9028726 | ||
|
|
e6638faffc | ||
|
|
f000530746 | ||
|
|
5bf04f841b | ||
|
|
5d95797aff | ||
|
|
9db2907a48 | ||
|
|
5423ae40d6 | ||
|
|
2de68acfea | ||
|
|
71e29b7388 | ||
|
|
6d6619cbb4 | ||
|
|
651053491e | ||
|
|
81f9919992 | ||
|
|
b57170d596 | ||
|
|
60462c033b | ||
|
|
3f597e59e0 | ||
|
|
a62051e5ff | ||
|
|
5483ddf024 | ||
|
|
62ef4b91fc | ||
|
|
8664521f08 | ||
|
|
6ef23916f0 | ||
|
|
73f8a2fb02 | ||
|
|
a552fc5329 | ||
|
|
505a91a6ed | ||
|
|
0d3b678800 | ||
|
|
efb115c2aa | ||
|
|
8721d285ce | ||
|
|
f421f9979d | ||
|
|
d5ad641102 | ||
|
|
ec6199c973 | ||
|
|
0eb09d097e | ||
|
|
13265b3d6b | ||
|
|
dbc7cd7bac | ||
|
|
4c1f36cda4 | ||
|
|
987af6ba16 | ||
|
|
58451ae18b | ||
|
|
cd2f5cbbfa | ||
|
|
896ff890d8 | ||
|
|
8ba24e39e0 | ||
|
|
0cf4e50e96 | ||
|
|
c8ad7eb0e2 | ||
|
|
42e47e8291 | ||
|
|
7d6c7d0735 | ||
|
|
16177a3b9d | ||
|
|
16a16460fc | ||
|
|
24d3351d5d | ||
|
|
daa06e5415 | ||
|
|
dc6cd1819d | ||
|
|
1ef1d858f8 | ||
|
|
74c75d36cc | ||
|
|
7a4264fe1e | ||
|
|
5decddeb42 | ||
|
|
0f08153214 | ||
|
|
5c3743e1f8 | ||
|
|
4a287f96fd | ||
|
|
0c35ae8d9e | ||
|
|
ddb2ff9b06 | ||
|
|
32398dd5fb | ||
|
|
cec252f98f | ||
|
|
c186198a7e | ||
|
|
ec46261757 | ||
|
|
ff0355ca9c | ||
|
|
2bd364fee8 | ||
|
|
823350a186 | ||
|
|
c58ddb4d66 | ||
|
|
447ec06234 | ||
|
|
21ca350946 | ||
|
|
46902e1c0c | ||
|
|
02bf302f96 | ||
|
|
76327fdf01 | ||
|
|
0044ed18ae | ||
|
|
a9bbb55220 | ||
|
|
69a2358d47 | ||
|
|
8664395e5b | ||
|
|
3c09b31f92 | ||
|
|
43e2eaa4db | ||
|
|
f3e98da13b | ||
|
|
25eaa2661a | ||
|
|
4f58a3d751 | ||
|
|
7d18083dda | ||
|
|
f0aca0a2ce | ||
|
|
18c76175b2 | ||
|
|
6dbde0c559 | ||
|
|
8fa9df6e7a | ||
|
|
e3382b1a62 | ||
|
|
29c7a21725 | ||
|
|
7a0ee9c7fa | ||
|
|
cb71277df4 | ||
|
|
9f5923864b | ||
|
|
60563f3e3c | ||
|
|
c49abf1608 | ||
|
|
250a794873 | ||
|
|
78f4a60bf7 | ||
|
|
2a93e33d38 | ||
|
|
5efd4d045f | ||
|
|
0516ba53bd | ||
|
|
1d76c0bc64 | ||
|
|
73bc1ab139 | ||
|
|
35fdb331e4 | ||
|
|
9ceda2059d | ||
|
|
0e24c9f453 | ||
|
|
ad54067b48 | ||
|
|
e99a58b430 | ||
|
|
51a5de71c1 | ||
|
|
06eca8cefa | ||
|
|
a4494159ea | ||
|
|
c95e25776e | ||
|
|
c2a5be6aa9 | ||
|
|
135eb71a75 | ||
|
|
af99120067 | ||
|
|
2d28520ae4 | ||
|
|
35d5b9efab | ||
|
|
f495303177 | ||
|
|
fb2e6b4074 | ||
|
|
4ffdee0002 | ||
|
|
5c5d53e1d1 | ||
|
|
269d2f5729 | ||
|
|
57149c2d03 | ||
|
|
838ebcb78f | ||
|
|
6298a7be9d | ||
|
|
cfea00b200 | ||
|
|
3d52919411 | ||
|
|
52ea1b5ba2 | ||
|
|
619a84949f | ||
|
|
c3648af57f | ||
|
|
53b5ea54c6 | ||
|
|
c4c7b9ec00 | ||
|
|
b428e7613d | ||
|
|
0e9534c10e | ||
|
|
7f8aa3f985 | ||
|
|
238e07e7d7 | ||
|
|
b6462ad865 | ||
|
|
2d7d854a97 | ||
|
|
0626737a15 | ||
|
|
17a1c9d639 | ||
|
|
31ea20dbd3 | ||
|
|
97c48c8901 | ||
|
|
bb339ba519 | ||
|
|
499f8418bf | ||
|
|
b84432ec7f | ||
|
|
111b514a05 | ||
|
|
90829dad51 | ||
|
|
943e433f7e | ||
|
|
02e6d0e04c | ||
|
|
1e7c92a107 | ||
|
|
2a97d699a8 | ||
|
|
2d0321e544 | ||
|
|
ebb209a371 | ||
|
|
ddd9430bc9 | ||
|
|
cc37877607 | ||
|
|
b35591ff8d | ||
|
|
29423f1f9a | ||
|
|
d51c57379a | ||
|
|
5f86aed17d | ||
|
|
99bd1fc8d5 | ||
|
|
70f2f9f1b7 | ||
|
|
cf9e33a4e4 | ||
|
|
c07d6f9c49 | ||
|
|
503a559b2a | ||
|
|
2dac3d1128 | ||
|
|
d7d87fed76 | ||
|
|
c08349517b | ||
|
|
f3774b5987 | ||
|
|
dccc7345ab | ||
|
|
7e51fb8371 | ||
|
|
0d7c9ac091 | ||
|
|
aee34fce32 | ||
|
|
c29d306d10 | ||
|
|
a5edc8071c | ||
|
|
106a673ba8 | ||
|
|
99fe01a0d6 | ||
|
|
94e496c77e | ||
|
|
5a9a694050 | ||
|
|
68c8046a55 | ||
|
|
c3fae61dda | ||
|
|
b783e5fa63 | ||
|
|
869a4e68a4 | ||
|
|
2ad827dfb9 | ||
|
|
fa745f2cfe | ||
|
|
e8cc443681 | ||
|
|
97fc6a10a4 | ||
|
|
d0218bfe54 | ||
|
|
b8b7ff882d | ||
|
|
c17b6a8821 | ||
|
|
2b489bae26 | ||
|
|
a9d4bf4a25 | ||
|
|
0d618efd0d | ||
|
|
5b0697b68c | ||
|
|
725b5f7932 | ||
|
|
2945d4ce08 | ||
|
|
14ff1451ce | ||
|
|
27716597d5 | ||
|
|
fd86520e91 | ||
|
|
815ed8e768 | ||
|
|
08f61b33f0 | ||
|
|
cb8f37bd2a | ||
|
|
b13277c156 | ||
|
|
b4438bbdfb | ||
|
|
5af711465d | ||
|
|
32cbad389a | ||
|
|
6022578901 | ||
|
|
740acf3664 | ||
|
|
46e07b2ec3 | ||
|
|
0318db838e | ||
|
|
04400b0d18 | ||
|
|
69c5572161 | ||
|
|
0d63932eab | ||
|
|
bb6c120691 | ||
|
|
e657f745f4 | ||
|
|
9a1c9173a3 | ||
|
|
dc648a5368 | ||
|
|
84651210e6 | ||
|
|
054183b73a | ||
|
|
d0612752f0 | ||
|
|
c3a1810890 | ||
|
|
51de6abbed | ||
|
|
94f4a239cc | ||
|
|
14a23268ad | ||
|
|
35a9bfe025 | ||
|
|
212bf3e96e | ||
|
|
9021a7ceec | ||
|
|
b56cf08319 | ||
|
|
a09ef9576d | ||
|
|
ea70bbc1b6 | ||
|
|
6fce88d93a | ||
|
|
82edb8cdf1 | ||
|
|
5ba70e05fc | ||
|
|
5c036059f8 | ||
|
|
a3c52ca679 | ||
|
|
f8138974c1 | ||
|
|
08908a5511 | ||
|
|
50df3e415d | ||
|
|
b3b385dd06 | ||
|
|
1047e9096a | ||
|
|
772afe4b5b | ||
|
|
6a791267a0 | ||
|
|
e9b7e13be1 | ||
|
|
516d64a1ff | ||
|
|
af7079f708 | ||
|
|
93502bb64b | ||
|
|
0b74716668 | ||
|
|
61a8f2adea | ||
|
|
4d9701613f | ||
|
|
90ab359ed3 | ||
|
|
8ef234dacf | ||
|
|
ea82ae5090 | ||
|
|
65aa347a9f | ||
|
|
3ba6d78241 | ||
|
|
0e2bb55483 | ||
|
|
c0b64f4bae | ||
|
|
6d70c0889d | ||
|
|
22a614bbf4 | ||
|
|
1fec5622b6 | ||
|
|
a1e2651b4c | ||
|
|
ec498ec476 | ||
|
|
e433ad319e | ||
|
|
30f9d01df9 | ||
|
|
579b592c12 | ||
|
|
dfbab9a7c0 | ||
|
|
d1730258bf | ||
|
|
1afd3e821a | ||
|
|
9e36b0fdc7 | ||
|
|
857637c1fb | ||
|
|
40854f6edb | ||
|
|
7f403b8050 | ||
|
|
2a59199870 | ||
|
|
6712d8c844 | ||
|
|
856da09741 | ||
|
|
c4cf410a59 | ||
|
|
0994dd4070 | ||
|
|
6cddce9f15 | ||
|
|
ac44fd59e3 | ||
|
|
5c25f9270c | ||
|
|
bfe301ae1c | ||
|
|
29aa64092a | ||
|
|
d9a0041870 | ||
|
|
ea3787e393 | ||
|
|
de2fe7f6be | ||
|
|
c548d1f2d8 | ||
|
|
fbe726e4c4 | ||
|
|
208ac286f8 | ||
|
|
9aef419c4c | ||
|
|
a2c6490d31 | ||
|
|
4b399995f5 | ||
|
|
877bb1f91f | ||
|
|
cd696e60ab | ||
|
|
9bd5a518ea | ||
|
|
fe4cc4b01d | ||
|
|
65d568c283 | ||
|
|
a118f110fa | ||
|
|
f803f29158 | ||
|
|
954c2d32c1 | ||
|
|
5112251894 | ||
|
|
545769885d | ||
|
|
94ea82c10a | ||
|
|
a6c978573f | ||
|
|
31d70dae49 | ||
|
|
9a639b40b7 | ||
|
|
e84f47abc8 | ||
|
|
741e4b0b30 | ||
|
|
52a720ec33 | ||
|
|
416c61a663 | ||
|
|
23bd296aeb | ||
|
|
2c8843fc86 | ||
|
|
aa07373c4e | ||
|
|
a3b5a44f79 | ||
|
|
d5fad8db39 | ||
|
|
ef5d703682 | ||
|
|
40efaf848e | ||
|
|
575854c8b9 | ||
|
|
3299947cc1 | ||
|
|
9daeea7400 | ||
|
|
4e51afc36c | ||
|
|
f1f333dc7a | ||
|
|
69a56ced7a | ||
|
|
2c468b0bb2 | ||
|
|
c67248ffc7 | ||
|
|
60936080da | ||
|
|
4db04564a9 | ||
|
|
f6b0ddc0b3 | ||
|
|
b42399e9a9 | ||
|
|
ba72056bf2 | ||
|
|
b8e4a51228 | ||
|
|
0b12f7db42 | ||
|
|
5053cffdad | ||
|
|
02f852604f | ||
|
|
e4ab8c56a0 | ||
|
|
86016d41d7 | ||
|
|
3fdfd07443 | ||
|
|
d801cdd722 | ||
|
|
72e5078ce9 | ||
|
|
a7c3f3dd35 | ||
|
|
729fc10674 | ||
|
|
12f0312b00 | ||
|
|
8c0e3e9dad | ||
|
|
c7104f0c0d | ||
|
|
679638beb2 | ||
|
|
f8fc5844b1 | ||
|
|
d86d8cf65a | ||
|
|
11e5b5fe95 | ||
|
|
42b623e9b0 | ||
|
|
21e65b8742 | ||
|
|
c6ac4d11be | ||
|
|
2d48e07139 | ||
|
|
3fee341ac2 | ||
|
|
2bed6776e4 | ||
|
|
01e0290d6e | ||
|
|
1c61154206 | ||
|
|
addf25ff16 | ||
|
|
578c1613d1 | ||
|
|
6073445551 | ||
|
|
30763684b7 | ||
|
|
ace8f44f59 | ||
|
|
98994bbeaa | ||
|
|
b089303505 | ||
|
|
8992e98c8d | ||
|
|
205245f269 | ||
|
|
b375041790 | ||
|
|
3a41665302 | ||
|
|
f6686b8188 | ||
|
|
31b43cf3c7 | ||
|
|
e483b19c14 | ||
|
|
50b400a1f8 | ||
|
|
d90dc35dd3 | ||
|
|
b45970b3b6 | ||
|
|
a5700cc914 | ||
|
|
d3c59cbff3 | ||
|
|
8bc1cc28d0 | ||
|
|
1ad9c321bc | ||
|
|
c9dede08d4 | ||
|
|
3b721112e6 | ||
|
|
0093fb8276 | ||
|
|
fe8137521a | ||
|
|
2bc7a1bb10 | ||
|
|
120ba0ba9a | ||
|
|
88d93737aa | ||
|
|
317d5a3aba | ||
|
|
ddc5cb0224 | ||
|
|
4b4ec17ff9 | ||
|
|
cc9534fc7b | ||
|
|
c8762821fb | ||
|
|
272dacdd3a | ||
|
|
78548460b7 | ||
|
|
3eee7a1409 | ||
|
|
e446782c1f | ||
|
|
d8664ca4c1 | ||
|
|
d06374a0f1 | ||
|
|
9a9c117411 | ||
|
|
2255dcc2bf | ||
|
|
be4402c1ff | ||
|
|
4d46dbe545 | ||
|
|
3fdf8d5a69 | ||
|
|
7c0aea0b1e | ||
|
|
b4d6c5ed2a | ||
|
|
d8e0674da0 | ||
|
|
b0df2e53a8 | ||
|
|
94ffdaf60d | ||
|
|
376aa5a8fa | ||
|
|
7fcc7af07d | ||
|
|
03d42555e7 | ||
|
|
b8624035e0 | ||
|
|
41b223a757 | ||
|
|
03fb1dc673 | ||
|
|
e864eca78d | ||
|
|
ddafc2e897 | ||
|
|
bf3f76e02e | ||
|
|
4398cd8677 | ||
|
|
dbf55eff3c | ||
|
|
07f894f66c | ||
|
|
a9737ca05e | ||
|
|
0e1750835e | ||
|
|
965cc52815 | ||
|
|
08ee154c09 | ||
|
|
37cacf3da4 | ||
|
|
55f7f94a6f | ||
|
|
1e91713bb6 | ||
|
|
27f52cac6b | ||
|
|
b0a144fd54 | ||
|
|
bfa4a23751 | ||
|
|
7c6568865c | ||
|
|
30c4a059af | ||
|
|
404cc417d6 | ||
|
|
ded6b69c3f | ||
|
|
e5cc71b4d2 | ||
|
|
7bc91e10de | ||
|
|
2033c6085f | ||
|
|
780b65a648 | ||
|
|
20b8c9700a | ||
|
|
b1b5e9197a | ||
|
|
252213fbc2 | ||
|
|
e696b737e3 | ||
|
|
153285bec0 | ||
|
|
304b87503e | ||
|
|
455f819ec0 | ||
|
|
2942c312a7 | ||
|
|
c6315365e2 | ||
|
|
7b6a91422d | ||
|
|
cb3daa3b63 | ||
|
|
2e6a3937d4 | ||
|
|
8a2ddac50e | ||
|
|
052c182278 | ||
|
|
e11c58cf3b | ||
|
|
df67cee38a | ||
|
|
7f1cdc8527 | ||
|
|
896727b664 | ||
|
|
b0a67878bb | ||
|
|
e8dab7daf7 | ||
|
|
e7c332ad0b | ||
|
|
e21ed5d2c5 | ||
|
|
2a8e6b36b3 | ||
|
|
8bc088d016 | ||
|
|
175e66cd43 | ||
|
|
849c5e2a90 | ||
|
|
538546f5fb | ||
|
|
25884e823e | ||
|
|
3cb239c202 | ||
|
|
c6a001bbc6 | ||
|
|
89f81bb7d6 | ||
|
|
52399ee812 | ||
|
|
7f735b7282 | ||
|
|
8e781e0b51 | ||
|
|
1ad63a7a37 | ||
|
|
7fcf65e9c3 | ||
|
|
63251ef650 | ||
|
|
befcddc994 | ||
|
|
7d7d5ddf2e | ||
|
|
760cb41a61 | ||
|
|
926e74fd02 | ||
|
|
86feafb721 | ||
|
|
57f66c0b99 | ||
|
|
05f964ee25 | ||
|
|
ff571539cb | ||
|
|
307db0d802 | ||
|
|
78bb93b288 | ||
|
|
756b48e7b6 | ||
|
|
2f975cd3d2 | ||
|
|
2b341c1a7f | ||
|
|
14ce832249 | ||
|
|
f7ccb79147 | ||
|
|
decae290d4 | ||
|
|
d51a1b10f0 | ||
|
|
a8867b1882 | ||
|
|
749d23705e | ||
|
|
a6849012a6 | ||
|
|
1f320dd7a2 | ||
|
|
46e5948425 | ||
|
|
b7eb3c9e90 | ||
|
|
9e5bdeb3a4 | ||
|
|
2cd74c7ff7 | ||
|
|
4c71e96cba | ||
|
|
f67d173aef | ||
|
|
a59465ff6e | ||
|
|
0bd1b82d3a | ||
|
|
65eac50c21 | ||
|
|
2a092c9495 | ||
|
|
10296f93e4 | ||
|
|
66cae656d1 | ||
|
|
b1ef744058 | ||
|
|
7d07db6526 | ||
|
|
a8e232e894 | ||
|
|
e99548ea8a | ||
|
|
5495e0e808 | ||
|
|
11e654ec90 | ||
|
|
4854fcf3e0 | ||
|
|
fb8bea390c | ||
|
|
fe22f0e449 | ||
|
|
c0abc9ce3c | ||
|
|
c39d81b71a | ||
|
|
9ab690b7c0 | ||
|
|
6cb207667d | ||
|
|
4c9f304a46 | ||
|
|
a9c4c6e049 | ||
|
|
4cd28b23f0 | ||
|
|
b2989efd5c | ||
|
|
cc4d1a15e4 | ||
|
|
7f25aff91d | ||
|
|
32f984de56 | ||
|
|
f01117d84e | ||
|
|
f3cd9a2664 | ||
|
|
fff425ec61 | ||
|
|
c78e082192 | ||
|
|
34ba94ae63 | ||
|
|
82e1297d77 | ||
|
|
25baeb4375 | ||
|
|
18d17beb93 | ||
|
|
34c18d47a4 | ||
|
|
6560137233 | ||
|
|
ada5748d2f | ||
|
|
c2e77cd005 | ||
|
|
8e3b47bf89 | ||
|
|
e7e7649d2f | ||
|
|
e63b6225f8 | ||
|
|
14fb0e7832 |
@@ -1 +0,0 @@
|
||||
github: a-j-wood
|
||||
+16
-1
@@ -1,3 +1,18 @@
|
||||
*~
|
||||
build-aux
|
||||
missing
|
||||
compile
|
||||
depcomp
|
||||
install-sh
|
||||
config.sub
|
||||
config.guess
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autoscan.log
|
||||
configure
|
||||
configure.scan
|
||||
autom4te.cache
|
||||
ABOUT-NLS
|
||||
m4
|
||||
*~
|
||||
*.tar.gz
|
||||
patch-backlog
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
SUBDIRS = po
|
||||
|
||||
bin_PROGRAMS = pv
|
||||
dist_doc_DATA = README.md docs/INSTALL docs/COPYING docs/NEWS.md docs/ACKNOWLEDGEMENTS.md docs/DEVELOPERS.md
|
||||
dist_man1_MANS = docs/pv.1
|
||||
|
||||
EXTRA_DIST = docs/pv.1.md docs/benchmark-rw-syscalls-vs-data.sh docs/benchmark-pv-transfers.sh docs/release.cf
|
||||
|
||||
pv_SOURCES = \
|
||||
src/main/debug.c \
|
||||
src/main/help.c \
|
||||
src/main/main.c \
|
||||
src/main/options.c \
|
||||
src/main/version.c \
|
||||
src/pv/calc.c \
|
||||
src/pv/cursor.c \
|
||||
src/pv/display.c \
|
||||
src/pv/elapsedtime.c \
|
||||
src/pv/file.c \
|
||||
src/pv/format/averagerate.c \
|
||||
src/pv/format/barstyle.c \
|
||||
src/pv/format/bufferpercent.c \
|
||||
src/pv/format/bytes.c \
|
||||
src/pv/format/conemu.c \
|
||||
src/pv/format/eta.c \
|
||||
src/pv/format/fineta.c \
|
||||
src/pv/format/lastwritten.c \
|
||||
src/pv/format/name.c \
|
||||
src/pv/format/previousline.c \
|
||||
src/pv/format/progressbar.c \
|
||||
src/pv/format/rate.c \
|
||||
src/pv/format/ratio.c \
|
||||
src/pv/format/sgr.c \
|
||||
src/pv/format/timer.c \
|
||||
src/pv/loop.c \
|
||||
src/pv/number.c \
|
||||
src/pv/proctitle.c \
|
||||
src/pv/remote.c \
|
||||
src/pv/signal.c \
|
||||
src/pv/state.c \
|
||||
src/pv/string.c \
|
||||
src/pv/transfer.c \
|
||||
src/pv/watchpid.c \
|
||||
src/include/config-aux.h \
|
||||
src/include/options.h \
|
||||
src/include/pv-internal.h \
|
||||
src/include/pv.h
|
||||
|
||||
## Allow tests to write diagnostic info to fd 9 to reach the original
|
||||
## stderr even when the test driver is sending test output to a file.
|
||||
AM_TESTS_FD_REDIRECT = 9>&2
|
||||
|
||||
AM_TESTS_ENVIRONMENT = \
|
||||
. $(srcdir)/tests/test-env.sh \
|
||||
;
|
||||
TESTS = \
|
||||
tests/Bug_-_Display_length_at_magnitude_boundary_-_Bytes.test \
|
||||
tests/Bug_-_Display_length_at_magnitude_boundary_-_Rate.test \
|
||||
tests/Bug_-_Install_all_files.test \
|
||||
tests/Display_-_--average-rate.test \
|
||||
tests/Display_-_--bits.test \
|
||||
tests/Display_-_--buffer-percent.test \
|
||||
tests/Display_-_--bytes.test \
|
||||
tests/Display_-_--eta_-_plausible_values.test \
|
||||
tests/Display_-_--fineta_-_plausible_values.test \
|
||||
tests/Display_-_--last-written.test \
|
||||
tests/Display_-_--numeric_--bytes_--line-mode.test \
|
||||
tests/Display_-_--numeric_--bytes.test \
|
||||
tests/Display_-_--numeric.test \
|
||||
tests/Display_-_--numeric_--timer.test \
|
||||
tests/Display_-_--progress_-_basic_movement.test \
|
||||
tests/Display_-_--progress_-_increasing.test \
|
||||
tests/Display_-_--quiet.test \
|
||||
tests/Display_-_--rate_-_displayed_value_changes.test \
|
||||
tests/Display_-_--timer_-_displayed_value_changes.test \
|
||||
tests/General_-_--pidfile.test \
|
||||
tests/General_-_--size_argument_handling.test \
|
||||
tests/Integrity_-_Basic.test \
|
||||
tests/Integrity_-_Binary_data.test \
|
||||
tests/Integrity_-_From_bursty_source.test \
|
||||
tests/Integrity_-_Large_file_support.test \
|
||||
tests/Integrity_-_On_closed_output_pipe_at_EOF.test \
|
||||
tests/Integrity_-_On_failed_input_pipe_at_EOF.test \
|
||||
tests/Integrity_-_On_output_pipe_close.test \
|
||||
tests/Integrity_-_When_adjusted_remotely.test \
|
||||
tests/Memory_safety_-_Basic.test \
|
||||
tests/Memory_safety_-_Process_title.test \
|
||||
tests/Memory_safety_-_Remote_control_receiver.test \
|
||||
tests/Memory_safety_-_Remote_control_sender.test \
|
||||
tests/Memory_safety_-_Watchfd.test \
|
||||
tests/Modifiers_-_--direct-io.test \
|
||||
tests/Modifiers_-_--force.test \
|
||||
tests/Modifiers_-_--interval.test \
|
||||
tests/Modifiers_-_--line-mode.test \
|
||||
tests/Modifiers_-_--size_from_file_size.test \
|
||||
tests/Modifiers_-_--size_from_dir_size.test \
|
||||
tests/Modifiers_-_--size.test \
|
||||
tests/Modifiers_-_--sync.test \
|
||||
tests/Monitor_-_Basic.test \
|
||||
tests/Sparse_-_Basic.test \
|
||||
tests/Terminal_-_Detect_width.test \
|
||||
tests/Transfer_-_--rate-limit.test \
|
||||
tests/Transfer_-_--remote.test \
|
||||
tests/Transfer_-_--stop-at-size.test \
|
||||
tests/Transfer_-_--stop-at-size_reads.test \
|
||||
tests/Watchfd_-_Multiple_arguments.test \
|
||||
tests/Watchfd_-_Multiple_descriptors.test \
|
||||
tests/Watchfd_-_Single_descriptor.test
|
||||
|
||||
EXTRA_DIST += $(TESTS) tests/run-valgrind.sh tests/test-env.sh
|
||||
|
||||
docs/pv.1.md: $(srcdir)/docs/pv.1
|
||||
test -d docs || mkdir docs
|
||||
pandoc --from man --to markdown < $< | sed '/\*\*\*\*/{s/\*//g;s/^/**/;s/$$/**/}' | sed '/^```/,/^```/d' | sed 's/^\\\[/[/' > $@
|
||||
|
||||
SUFFIXES = .c .o .e
|
||||
|
||||
.c.e:
|
||||
-splint -badflag +posixlib $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) -DSPLINT=1 $< > $@ 2>&1
|
||||
-flawfinder $< >> $@ 2>&1
|
||||
|
||||
indent:
|
||||
cd $(srcdir) && indent -npro -kr -i8 -cd42 -c45 -l120 src/*/*.c src/*/*/*.c
|
||||
|
||||
indentclean:
|
||||
rm -f $(srcdir)/src/*/*.c~ $(srcdir)/src/*/*/*.c~
|
||||
|
||||
analyse: $(pv_SOURCES:.c=.e) FORCE
|
||||
grep -E -e '^Finished checking --' -e 'Hits = ' $+ 2>/dev/null || true
|
||||
|
||||
FORCE:
|
||||
|
||||
clean-local:
|
||||
rm -f src/*/*.e src/*/*/*.e
|
||||
|
||||
# Convenience alias for "make check": "make test"
|
||||
test: check
|
||||
|
||||
# Generate a package manifest if MAINTAINER is set.
|
||||
dist-hook:
|
||||
if test -n "$(MAINTAINER)"; then \
|
||||
cd "$(top_distdir)" \
|
||||
&& { printf "%s\n\n" "Check file integrity with 'sha512sum -c MANIFEST && echo OK'."; \
|
||||
find -type f -not -name MANIFEST -exec sha512sum '{}' ';' | sort -k 2; } \
|
||||
| gpg -u "$(MAINTAINER)" --clearsign > MANIFEST; \
|
||||
else true; fi
|
||||
|
||||
# "release" target - requires MAINTAINER variable to select GPG key.
|
||||
release: distcheck
|
||||
gpg --list-secret-keys 2>&1 | grep -F 'uid' | grep -Fq "$(MAINTAINER)"
|
||||
gpg -u "$(MAINTAINER)" -ab $(distdir).tar.gz
|
||||
cp -f $(distdir).tar.gz.asc $(distdir).tar.gz.txt
|
||||
chmod 644 $(distdir).tar.gz $(distdir).tar.gz.asc $(distdir).tar.gz.txt
|
||||
@@ -1,53 +1,92 @@
|
||||
Introduction
|
||||
------------
|
||||
# Introduction
|
||||
|
||||
This is the README for **pv** ("Pipe Viewer"), a terminal-based tool for
|
||||
monitoring the progress of data through a pipeline. It can be inserted into
|
||||
any normal pipeline between two processes to give a visual indication of how
|
||||
quickly data is passing through, how long it has taken, how near to
|
||||
completion it is, and an estimate of how long it will be until completion.
|
||||
**pv** ("Pipe Viewer") is a terminal-based tool for monitoring the progress
|
||||
of data through a pipeline and modifying its flow.
|
||||
|
||||
When used just like "**cat**", **pv** displays how quickly data is being
|
||||
transferred, how long it has taken, how near to completion it is, and an
|
||||
estimate of how long it will be until completion. Data flow rate, error
|
||||
handling strategy, buffer size, and cache interaction can all be adjusted.
|
||||
|
||||
With the "**\--cursor**" option, several **pv** instances can work together,
|
||||
showing transfer progress at different points in the same pipeline.
|
||||
|
||||
In "**\--watchfd**" mode, **pv** will inspect another process and show its
|
||||
progress through the files it has open.
|
||||
|
||||
In "**\--monitor**" mode, **pv** will run a command and display the progress
|
||||
of data through both its standard input and its standard output.
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
# Documentation
|
||||
|
||||
A manual page is included in this distribution. See "`man ./doc/quickref.1`",
|
||||
or "`man pv`" after installation.
|
||||
A manual page is included in this distribution ("`man pv`"). Before
|
||||
installation, it is in "[docs/pv.1](./docs/pv.1.md)".
|
||||
|
||||
Changes are listed in "[doc/NEWS.md](./doc/NEWS.md)". The to-do list is "[doc/TODO.md](./doc/TODO.md)".
|
||||
Changes are listed in "[docs/NEWS.md](./docs/NEWS.md)".
|
||||
|
||||
Developers and translators, please see "[doc/DEVELOPERS.md](./doc/DEVELOPERS.md)".
|
||||
Developers and translators, please see "[docs/DEVELOPERS.md](./docs/DEVELOPERS.md)".
|
||||
|
||||
Translators can use the Weblate instance hosted by Codeberg:
|
||||
[https://translate.codeberg.org/engage/pv/](https://translate.codeberg.org/engage/pv/)
|
||||
|
||||
[](https://translate.codeberg.org/engage/pv/)
|
||||
|
||||
If you don't see your language listed, raise an issue on the issue tracker
|
||||
(or just email the maintainer) asking for it to be added.
|
||||
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
# Installation
|
||||
|
||||
If this is not a packaged release, first run "`./generate.sh`".
|
||||
See "[docs/INSTALL](./docs/INSTALL)" for more about the _configure_ script.
|
||||
|
||||
To compile the package, type "`sh ./configure`", which should generate a
|
||||
Makefile for your system. You may then type "`make`" to build everything.
|
||||
Note that GNU _make_ is required; this may be installed as _gmake_ on some
|
||||
systems, so if typing "`make`" gives an error, try "`gmake`" instead.
|
||||
The typical process for a system-wide install is:
|
||||
|
||||
See the file "[doc/INSTALL](./doc/INSTALL)" for more about the _configure_ script.
|
||||
sh ./configure --prefix=/usr
|
||||
make
|
||||
sudo make install
|
||||
|
||||
This requires the build toolchain ("`sudo apt install build-essential`" on
|
||||
Debian or Ubuntu systems).
|
||||
|
||||
If this is not a packaged release, the _configure_ script is not included.
|
||||
It is generated with the GNU build system tools (_autoconf_, _aclocal_,
|
||||
_autopoint_, _automake_); _gettext_ is also needed. On Debian or Ubuntu,
|
||||
run "`sudo apt install automake autopoint gettext`". Once those tools are
|
||||
in place, call "`autoreconf -is`" to generate the _configure_ script, and
|
||||
run it as described above.
|
||||
|
||||
|
||||
Author and acknowledgements
|
||||
---------------------------
|
||||
# Copyright, bug reporting, and acknowledgements
|
||||
|
||||
This package is copyright 2023 Andrew Wood, and is being distributed under
|
||||
the terms of the Artistic License 2.0. For more details of this license,
|
||||
see the file "[doc/COPYING](./doc/COPYING)".
|
||||
See "[docs/ACKNOWLEDGEMENTS.md](./docs/ACKNOWLEDGEMENTS.md)" for a list of
|
||||
contributors.
|
||||
|
||||
Report bugs in **pv** using the contact form linked from the home page, or
|
||||
though the [project issue tracker](https://github.com/a-j-wood/pv/issues).
|
||||
Copyright (C) 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood.
|
||||
|
||||
License GPLv3+: GNU GPL version 3 or later <https://www.gnu.org/licenses/gpl-3.0.html>.
|
||||
|
||||
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, version
|
||||
3, in "[docs/COPYING](./docs/COPYING)". If not, see
|
||||
<https://www.gnu.org/licenses/gpl-3.0.html>.
|
||||
|
||||
Please report bugs or request features via the issue tracker linked from the
|
||||
home page.
|
||||
|
||||
The **pv** home page is at:
|
||||
|
||||
[http://www.ivarch.com/programs/pv.shtml](http://www.ivarch.com/programs/pv.shtml)
|
||||
> [https://ivarch.com/p/pv](https://ivarch.com/p/pv)
|
||||
|
||||
The latest version can always be found here.
|
||||
|
||||
**Please see "[doc/ACKNOWLEDGEMENTS.md](./doc/ACKNOWLEDGEMENTS.md)" for a list of contributors.**
|
||||
|
||||
---
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#
|
||||
# Files from which this is generated (inside directory `autoconf/make'):
|
||||
#
|
||||
# package.mk # package name and distribution details
|
||||
# vars.mk # compilation, shell and linking variables
|
||||
# filelist.mk~ # lists of files (generated by "makemake.sh")
|
||||
# unreal.mk # phony targets
|
||||
# modules.mk~ # module linking rules (generated by "makemake.sh")
|
||||
# rules.mk # compilation rules
|
||||
# link.mk # real top-level targets
|
||||
# depend.mk~ # dependencies (generated by "makemake.sh")
|
||||
#
|
||||
#
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl
|
||||
dnl Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
dnl
|
||||
dnl Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([src/main/version.c])
|
||||
AC_CONFIG_AUX_DIR(autoconf/scripts)
|
||||
AC_CONFIG_HEADERS([src/include/config.h:autoconf/header.in])
|
||||
AH_BOTTOM([#include "config-aux.h"])
|
||||
|
||||
dnl Package identity
|
||||
PACKAGE=`cat $srcdir/doc/PACKAGE`
|
||||
VERSION=`cat $srcdir/doc/VERSION`
|
||||
UCPACKAGE=`tr a-z A-Z < $srcdir/doc/PACKAGE`
|
||||
AC_SUBST(PACKAGE)
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(UCPACKAGE)
|
||||
AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Package name])
|
||||
AC_DEFINE_UNQUOTED([PROGRAM_NAME], ["$PACKAGE"], [Name of this program])
|
||||
AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version of this program])
|
||||
AC_DEFINE([COPYRIGHT_YEAR], [_("2023")], [Copyright year])
|
||||
AC_DEFINE([COPYRIGHT_HOLDER], [_("Andrew Wood <andrew.wood@ivarch.com>")], [Copyright holder])
|
||||
AC_DEFINE([PROJECT_HOMEPAGE], ["http://www.ivarch.com/programs/" PROGRAM_NAME ".shtml"], [Project homepage])
|
||||
AC_DEFINE([BUG_REPORTS_TO], [_("<pv@ivarch.com>")], [Bug reporting email address])
|
||||
|
||||
AC_LANG(C)
|
||||
CFLAGS=${CFLAGS:-"-O"}
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_C_CONST
|
||||
AC_HEADER_STDBOOL
|
||||
AC_SYS_LARGEFILE
|
||||
AC_HEADER_TIOCGWINSZ
|
||||
AC_CHECK_FUNCS(getopt_long getopt)
|
||||
AC_CHECK_HEADERS(getopt.h)
|
||||
AC_CHECK_FUNCS(memcpy basename vsnprintf strlcat)
|
||||
AC_CHECK_FUNCS(fdatasync)
|
||||
AC_CHECK_FUNCS(fpathconf sysconf posix_memalign)
|
||||
AC_CHECK_HEADERS(limits.h)
|
||||
AC_CHECK_HEADERS(wctype.h)
|
||||
AC_CHECK_HEADERS(termios.h)
|
||||
|
||||
AC_ARG_ENABLE(debugging,
|
||||
[ --enable-debugging compile with debugging support],
|
||||
if test "$enable_debugging" = "yes"; then
|
||||
CFLAGS="$CFLAGS -g -Wall"
|
||||
AC_DEFINE([ENABLE_DEBUGGING], [1], [Debugging support enabled])
|
||||
fi
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(profiling,
|
||||
[ --enable-profiling compile with profiling support],
|
||||
if test "$enable_profiling" = "yes"; then
|
||||
CFLAGS="-pg $CFLAGS"
|
||||
fi
|
||||
)
|
||||
|
||||
STATIC_NLS="no"
|
||||
AC_ARG_ENABLE(static-nls, [ --enable-static-nls hardcode NLS with no support files],
|
||||
if test "$enable_static_nls" = "yes"; then
|
||||
STATIC_NLS="yes"
|
||||
fi,
|
||||
STATIC_NLS="no"
|
||||
)
|
||||
|
||||
NLS_SUPPORT="no"
|
||||
AC_ARG_ENABLE(nls, [ --disable-nls do not use Native Language Support],
|
||||
if test "$enable_nls" = "yes"; then
|
||||
NLS_SUPPORT="yes"
|
||||
fi,
|
||||
NLS_SUPPORT="yes"
|
||||
)
|
||||
|
||||
SPLICE_SUPPORT="no"
|
||||
AC_ARG_ENABLE(splice, [ --disable-splice do not use splice system call],
|
||||
if test "$enable_splice" = "yes"; then
|
||||
SPLICE_SUPPORT="yes"
|
||||
fi,
|
||||
SPLICE_SUPPORT="yes"
|
||||
)
|
||||
|
||||
IPC_SUPPORT="no"
|
||||
AC_ARG_ENABLE(ipc, [ --disable-ipc turn off IPC messaging],
|
||||
if test "$enable_ipc" = "yes"; then
|
||||
IPC_SUPPORT="yes"
|
||||
fi,
|
||||
IPC_SUPPORT="yes"
|
||||
)
|
||||
|
||||
dnl AIX needs -lc128
|
||||
AC_EGREP_CPP([^yes$], [#ifdef _AIX
|
||||
yes
|
||||
#endif
|
||||
], [LIBS="$LIBS -lc128"])
|
||||
|
||||
dnl Native Language Support
|
||||
if test "$NLS_SUPPORT" = "yes"; then
|
||||
AC_DEFINE([ENABLE_NLS], [1], [Enable native language support])
|
||||
AC_PATH_PROG(MSGFMT, msgfmt, NOMSGFMT)
|
||||
AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
|
||||
AC_PATH_PROG(XGETTEXT, xgettext, xgettext)
|
||||
if test "x$MSGFMT" = "xNOMSGFMT"; then
|
||||
MSGFMT=""
|
||||
STATIC_NLS="yes"
|
||||
fi
|
||||
if test "$STATIC_NLS" = "yes"; then
|
||||
CATALOGS=""
|
||||
NLSOBJ="src/nls/table.o"
|
||||
else
|
||||
AC_CHECK_LIB(intl, main)
|
||||
AC_CHECK_LIB(i, main)
|
||||
fi
|
||||
CATOBJEXT=.mo
|
||||
INSTOBJEXT=.mo
|
||||
for lang in de fr pl pt; do
|
||||
GMOFILES="$GMOFILES $lang.gmo"
|
||||
POFILES="$POFILES \$(srcdir)/src/nls/$lang.po"
|
||||
CATALOGS="$CATALOGS src/nls/$lang$CATOBJEXT";
|
||||
done
|
||||
if test "$STATIC_NLS" = "yes"; then
|
||||
CATALOGS=""
|
||||
else
|
||||
AC_CHECK_FUNC(gettext,
|
||||
[AC_DEFINE([HAVE_GETTEXT], [1], [The gettext function is available])
|
||||
NLSOBJ=""
|
||||
], [CATALOGS=""; NLSOBJ="src/nls/table.o"
|
||||
]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
AC_CHECK_HEADERS(libintl.h)
|
||||
AC_CHECK_HEADERS(locale.h)
|
||||
AC_SUBST(MSGFMT)
|
||||
AC_SUBST(GMSGFMT)
|
||||
AC_SUBST(XGETTEXT)
|
||||
AC_SUBST(CATOBJEXT)
|
||||
AC_SUBST(INSTOBJEXT)
|
||||
AC_SUBST(GMOFILES)
|
||||
AC_SUBST(POFILES)
|
||||
AC_SUBST(CATALOGS)
|
||||
AC_SUBST(NLSOBJ)
|
||||
|
||||
if test "$IPC_SUPPORT" = "yes"; then
|
||||
AC_CHECK_HEADERS(sys/ipc.h sys/param.h libgen.h)
|
||||
fi
|
||||
|
||||
if test "$SPLICE_SUPPORT" = "yes"; then
|
||||
AC_CHECK_FUNCS(splice)
|
||||
fi
|
||||
|
||||
dnl This must go after all the compiler based tests above.
|
||||
AC_LANG_WERROR
|
||||
|
||||
dnl Fudging for separate build directories.
|
||||
dnl
|
||||
subdirs=""
|
||||
for i in `find $srcdir/src -type d -print | sed s,$srcdir/,,`; do
|
||||
subdirs="$subdirs $i"
|
||||
done
|
||||
|
||||
dnl Stitch together the Makefile fragments.
|
||||
dnl
|
||||
mk_segments="autoconf/Makefile.in"
|
||||
for i in vars.mk package.mk filelist.mk~ unreal.mk modules.mk~ \
|
||||
rules.mk link.mk depend.mk~; do
|
||||
mk_segments="$mk_segments:autoconf/make/$i"
|
||||
done
|
||||
|
||||
dnl Output files (and create build directory structure too).
|
||||
dnl
|
||||
AC_CONFIG_FILES([Makefile:$mk_segments doc/lsm:doc/lsm.in
|
||||
doc/quickref.1:doc/quickref.1.in
|
||||
src/.dummy:doc/NEWS.md])
|
||||
AC_CONFIG_COMMANDS([default],[rm -f src/.dummy
|
||||
for i in $subdirs; do
|
||||
test -d $i || mkdir $i
|
||||
done
|
||||
],[subdirs="$subdirs"])
|
||||
AC_OUTPUT
|
||||
|
||||
dnl EOF
|
||||
@@ -1,261 +0,0 @@
|
||||
/* autoconf/header.in. Generated from autoconf/configure.in by autoheader. */
|
||||
|
||||
/* Bug reporting email address */
|
||||
#undef BUG_REPORTS_TO
|
||||
|
||||
/* Copyright holder */
|
||||
#undef COPYRIGHT_HOLDER
|
||||
|
||||
/* Copyright year */
|
||||
#undef COPYRIGHT_YEAR
|
||||
|
||||
/* Debugging support enabled */
|
||||
#undef ENABLE_DEBUGGING
|
||||
|
||||
/* Enable native language support */
|
||||
#undef ENABLE_NLS
|
||||
|
||||
/* Define to 1 if `TIOCGWINSZ' requires <sys/ioctl.h>. */
|
||||
#undef GWINSZ_IN_SYS_IOCTL
|
||||
|
||||
/* Define to 1 if you have the `basename' function. */
|
||||
#undef HAVE_BASENAME
|
||||
|
||||
/* Define to 1 if you have the `fdatasync' function. */
|
||||
#undef HAVE_FDATASYNC
|
||||
|
||||
/* Define to 1 if you have the `fpathconf' function. */
|
||||
#undef HAVE_FPATHCONF
|
||||
|
||||
/* Define to 1 if you have the `getopt' function. */
|
||||
#undef HAVE_GETOPT
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
/* The gettext function is available */
|
||||
#undef HAVE_GETTEXT
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#undef HAVE_LIBGEN_H
|
||||
|
||||
/* Define to 1 if you have the `i' library (-li). */
|
||||
#undef HAVE_LIBI
|
||||
|
||||
/* Define to 1 if you have the `intl' library (-lintl). */
|
||||
#undef HAVE_LIBINTL
|
||||
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
#undef HAVE_LIBINTL_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* Define to 1 if you have the <minix/config.h> header file. */
|
||||
#undef HAVE_MINIX_CONFIG_H
|
||||
|
||||
/* Define to 1 if you have the `posix_memalign' function. */
|
||||
#undef HAVE_POSIX_MEMALIGN
|
||||
|
||||
/* Define to 1 if you have the `splice' function. */
|
||||
#undef HAVE_SPLICE
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#undef HAVE_STDBOOL_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#undef HAVE_STDIO_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
#undef HAVE_STRLCAT
|
||||
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#undef HAVE_SYSCONF
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#undef HAVE_TERMIOS_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#undef HAVE_WCHAR_H
|
||||
|
||||
/* Define to 1 if you have the <wctype.h> header file. */
|
||||
#undef HAVE_WCTYPE_H
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#undef HAVE__BOOL
|
||||
|
||||
/* Package name */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Name of this program */
|
||||
#undef PROGRAM_NAME
|
||||
|
||||
/* Project homepage */
|
||||
#undef PROJECT_HOMEPAGE
|
||||
|
||||
/* Define to 1 if all of the C90 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
backward compatibility; new code need not use it. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on macOS. */
|
||||
#ifndef _DARWIN_C_SOURCE
|
||||
# undef _DARWIN_C_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable X/Open compliant socket functions that do not require linking
|
||||
with -lxnet on HP-UX 11.11. */
|
||||
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
|
||||
# undef _HPUX_ALT_XOPEN_SOCKET_API
|
||||
#endif
|
||||
/* Identify the host operating system as Minix.
|
||||
This macro does not affect the system headers' behavior.
|
||||
A future release of Autoconf may stop defining this macro. */
|
||||
#ifndef _MINIX
|
||||
# undef _MINIX
|
||||
#endif
|
||||
/* Enable general extensions on NetBSD.
|
||||
Enable NetBSD compatibility extensions on Minix. */
|
||||
#ifndef _NETBSD_SOURCE
|
||||
# undef _NETBSD_SOURCE
|
||||
#endif
|
||||
/* Enable OpenBSD compatibility extensions on NetBSD.
|
||||
Oddly enough, this does nothing on OpenBSD. */
|
||||
#ifndef _OPENBSD_SOURCE
|
||||
# undef _OPENBSD_SOURCE
|
||||
#endif
|
||||
/* Define to 1 if needed for POSIX-compatible behavior. */
|
||||
#ifndef _POSIX_SOURCE
|
||||
# undef _POSIX_SOURCE
|
||||
#endif
|
||||
/* Define to 2 if needed for POSIX-compatible behavior. */
|
||||
#ifndef _POSIX_1_SOURCE
|
||||
# undef _POSIX_1_SOURCE
|
||||
#endif
|
||||
/* Enable POSIX-compatible threading on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
|
||||
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
|
||||
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_BFP_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_DFP_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
|
||||
#ifndef __STDC_WANT_LIB_EXT2__
|
||||
# undef __STDC_WANT_LIB_EXT2__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC 24747:2009. */
|
||||
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
|
||||
# undef __STDC_WANT_MATH_SPEC_FUNCS__
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable X/Open extensions. Define to 500 only if necessary
|
||||
to make mbstate_t available. */
|
||||
#ifndef _XOPEN_SOURCE
|
||||
# undef _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
|
||||
/* Version of this program */
|
||||
#undef VERSION
|
||||
|
||||
/* 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
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
#include "config-aux.h"
|
||||
@@ -1,11 +0,0 @@
|
||||
#
|
||||
# Targets.
|
||||
#
|
||||
|
||||
$(package): src/main.o src/library.o src/pv.o @NLSOBJ@
|
||||
$(CC) $(LINKFLAGS) $(CFLAGS) -o $@ src/main.o src/library.o src/pv.o @NLSOBJ@ $(LIBS)
|
||||
|
||||
$(package)-static: src/main.o src/library.o src/pv.o @NLSOBJ@
|
||||
$(CC) $(LINKFLAGS) $(CFLAGS) -static -o $@ src/main.o src/library.o src/pv.o @NLSOBJ@ $(LIBS)
|
||||
|
||||
# EOF
|
||||
@@ -1,17 +0,0 @@
|
||||
#
|
||||
# Package name, version, and distribution files.
|
||||
#
|
||||
|
||||
package = @PACKAGE@
|
||||
version = @VERSION@
|
||||
PACKAGE = @PACKAGE@
|
||||
|
||||
distfiles = \
|
||||
$(srcdir)/README.md \
|
||||
$(srcdir)/autoconf \
|
||||
$(srcdir)/configure \
|
||||
$(srcdir)/doc \
|
||||
$(srcdir)/src \
|
||||
$(srcdir)/tests
|
||||
|
||||
# EOF
|
||||
@@ -1,47 +0,0 @@
|
||||
#
|
||||
# Compilation rules.
|
||||
#
|
||||
|
||||
.SUFFIXES: .c .d .o .e
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
.c.d:
|
||||
sh $(srcdir)/autoconf/scripts/depend.sh \
|
||||
$(CC) $< $(<:%.c=%) $(srcdir) $(CFLAGS) $(CPPFLAGS) > $@
|
||||
|
||||
.c.e:
|
||||
-splint -badflag +posixlib $(CPPFLAGS) $< > $@ 2>&1
|
||||
-flawfinder $< >> $@ 2>&1
|
||||
|
||||
#
|
||||
# Native language support
|
||||
#
|
||||
|
||||
%.mo: %.po
|
||||
$(MSGFMT) -o $@ $<
|
||||
@touch $@
|
||||
@chmod 644 $@
|
||||
|
||||
%.gmo: %.po
|
||||
rm -f $@
|
||||
$(GMSGFMT) -o $@ $<
|
||||
@touch $@
|
||||
@chmod 644 $@
|
||||
|
||||
$(srcdir)/src/nls/$(PACKAGE).pot: $(allsrc)
|
||||
$(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(srcdir) \
|
||||
--add-comments --keyword=_ --keyword=N_ \
|
||||
$(allsrc)
|
||||
if cmp -s $(PACKAGE).po $@; then \
|
||||
rm -f $(PACKAGE).po; \
|
||||
else \
|
||||
rm -f $@; \
|
||||
mv $(PACKAGE).po $@; \
|
||||
chmod 644 $@; \
|
||||
fi
|
||||
|
||||
src/nls/table.c: $(POFILES)
|
||||
sh $(srcdir)/autoconf/scripts/po2table.sh $(POFILES) > src/nls/table.c
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
#
|
||||
# Rules for all phony targets.
|
||||
#
|
||||
|
||||
.PHONY: all help make dep depend test check analyse \
|
||||
clean depclean analysisclean indentclean distclean gitclean \
|
||||
index manhtml indent update-po \
|
||||
doc dist release \
|
||||
install uninstall
|
||||
|
||||
all: $(alltarg) $(CATALOGS)
|
||||
|
||||
help:
|
||||
@echo 'This Makefile has the following utility targets:'
|
||||
@echo
|
||||
@echo ' all build all binary targets'
|
||||
@echo ' install install compiled package and manual'
|
||||
@echo ' uninstall uninstall the package'
|
||||
@echo ' check / test run standardised tests on the compiled binary'
|
||||
@echo
|
||||
@echo 'Developer targets:'
|
||||
@echo
|
||||
@echo ' make rebuild the Makefile (after adding new files)'
|
||||
@echo ' dep / depend rebuild .d (dependency) files'
|
||||
@echo ' analyse run analysis tools on all .c files'
|
||||
@echo ' clean remove .o (object) files'
|
||||
@echo ' depclean remove .d (dependency) files'
|
||||
@echo ' analysisclean remove .e (analysis) files'
|
||||
@echo ' indentclean remove files left over from "make indent"'
|
||||
@echo ' distclean remove everything not distributed'
|
||||
@echo ' gitclean remove everything not in version control'
|
||||
@echo
|
||||
@echo ' index generate an HTML index of source code'
|
||||
@echo ' manhtml output HTML man page to stdout'
|
||||
@echo ' indent reformat all source files with "indent"'
|
||||
@echo ' update-po update the .po files'
|
||||
@echo
|
||||
@echo ' dist create a source tarball for distribution'
|
||||
@echo ' release create and sign tar.gz and tar.bz2'
|
||||
@echo
|
||||
|
||||
make:
|
||||
echo > $(srcdir)/autoconf/make/filelist.mk~
|
||||
echo > $(srcdir)/autoconf/make/modules.mk~
|
||||
cd $(srcdir); \
|
||||
bash autoconf/scripts/makemake.sh \
|
||||
autoconf/make/filelist.mk~ \
|
||||
autoconf/make/modules.mk~
|
||||
sh ./config.status
|
||||
|
||||
dep depend: $(alldep)
|
||||
echo '#' > $(srcdir)/autoconf/make/depend.mk~
|
||||
echo '# Dependencies.' >> $(srcdir)/autoconf/make/depend.mk~
|
||||
echo '#' >> $(srcdir)/autoconf/make/depend.mk~
|
||||
echo >> $(srcdir)/autoconf/make/depend.mk~
|
||||
cat $(alldep) >> $(srcdir)/autoconf/make/depend.mk~
|
||||
sh ./config.status
|
||||
|
||||
analyse: $(allanalysis)
|
||||
|
||||
clean:
|
||||
rm -f $(allobj)
|
||||
|
||||
depclean:
|
||||
rm -f $(alldep)
|
||||
|
||||
analysisclean:
|
||||
rm -f $(allanalysis)
|
||||
|
||||
indentclean:
|
||||
cd $(srcdir) && for FILE in $(allsrc); do rm -f ./$${FILE}~; done
|
||||
|
||||
update-po: $(srcdir)/src/nls/$(PACKAGE).pot
|
||||
catalogs='$(CATALOGS)'; \
|
||||
for cat in $$catalogs; do \
|
||||
lang=$(srcdir)/`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \
|
||||
mv $$lang.po $$lang.old.po; \
|
||||
if $(MSGMERGE) $$lang.old.po $(srcdir)/src/nls/$(PACKAGE).pot > $$lang.po; then \
|
||||
rm -f $$lang.old.po; \
|
||||
else \
|
||||
echo "msgmerge for $$cat failed!"; \
|
||||
rm -f $$lang.po; \
|
||||
mv $$lang.old.po $$lang.po; \
|
||||
chmod 644 $$lang.po; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
distclean: clean depclean analysisclean
|
||||
rm -f $(alltarg) src/include/config.h
|
||||
rm -rf $(package)-$(version).tar* $(package)-$(version)
|
||||
rm -f *.html config.*
|
||||
rm Makefile
|
||||
|
||||
gitclean: distclean
|
||||
rm -f doc/lsm
|
||||
rm -f doc/quickref.1
|
||||
rm -f configure
|
||||
rm -f src/nls/*.gmo src/nls/*.mo
|
||||
echo > $(srcdir)/autoconf/make/depend.mk~
|
||||
echo > $(srcdir)/autoconf/make/filelist.mk~
|
||||
echo > $(srcdir)/autoconf/make/modules.mk~
|
||||
|
||||
doc:
|
||||
-true
|
||||
|
||||
index:
|
||||
(cd $(srcdir); sh autoconf/scripts/index.sh $(srcdir)) > index.html
|
||||
|
||||
manhtml:
|
||||
@man2html ./doc/quickref.1 \
|
||||
| sed -e '1,/<BODY/d' -e '/<\/BODY/,$$d' \
|
||||
-e 's|<A [^>]*> </A>||ig' \
|
||||
-e 's|<A [^>]*>\([^<]*\)</A>|\1|ig' \
|
||||
-e '/<H1/d' -e 's|\(</H[0-9]>\)|\1<P>|ig' \
|
||||
-e 's/<DL COMPACT>/<DL>/ig' \
|
||||
-e 's/<[0-9A-Za-z_.-]\+@[0-9A-Za-z_.-]\+>//g' \
|
||||
-e 's|<I>\(http://.*\)</I>|<A HREF="\1">\1</A>|ig' \
|
||||
| sed -e '1,/<HR/d' -e '/<H2>Index/,/<HR/d' \
|
||||
|
||||
indent:
|
||||
cd $(srcdir) && indent -npro -kr -i8 -cd42 -c45 -l120 $(allsrc)
|
||||
|
||||
dist: doc update-po
|
||||
rm -rf $(package)-$(version)
|
||||
mkdir $(package)-$(version)
|
||||
cp -dprf Makefile $(distfiles) $(package)-$(version)
|
||||
cd $(package)-$(version); $(MAKE) distclean
|
||||
cp -dpf doc/lsm $(package)-$(version)/doc/
|
||||
chmod 644 `find $(package)-$(version) -type f -print`
|
||||
chmod 755 `find $(package)-$(version) -type d -print`
|
||||
chmod 755 `find $(package)-$(version)/autoconf/scripts`
|
||||
chmod 755 $(package)-$(version)/configure
|
||||
rm -rf DUMMY `find $(package)-$(version) -type d -name CVS`
|
||||
rm -rf DUMMY `find $(package)-$(version) -type d -name .svn`
|
||||
tar cf $(package)-$(version).tar $(package)-$(version)
|
||||
rm -rf $(package)-$(version)
|
||||
-gzip -f9 $(package)-$(version).tar
|
||||
|
||||
check test: $(alltarg)
|
||||
sh $(srcdir)/autoconf/scripts/run-test.sh ./$(package) $(srcdir)
|
||||
|
||||
install: all doc
|
||||
$(srcdir)/autoconf/scripts/mkinstalldirs \
|
||||
"$(DESTDIR)$(bindir)"
|
||||
$(srcdir)/autoconf/scripts/mkinstalldirs \
|
||||
"$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL) -m 755 $(package) \
|
||||
"$(DESTDIR)$(bindir)/$(package)"
|
||||
$(INSTALL) -m 644 doc/quickref.1 \
|
||||
"$(DESTDIR)$(mandir)/man1/$(package).1"
|
||||
if test -n "$(CATALOGS)"; then \
|
||||
catalogs='$(CATALOGS)'; \
|
||||
for cat in $$catalogs; do \
|
||||
name=`echo $$cat | sed 's,^.*/,,g'`; \
|
||||
if test "`echo $$name | sed 's/.*\(\..*\)/\1/'`" = ".gmo"; then \
|
||||
destdir=$(gnulocaledir); \
|
||||
else \
|
||||
destdir=$(localedir); \
|
||||
fi; \
|
||||
lang=`echo $$name | sed 's/$(CATOBJEXT)$$//'`; \
|
||||
dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \
|
||||
$(srcdir)/autoconf/scripts/mkinstalldirs $$dir; \
|
||||
$(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
|
||||
done; \
|
||||
fi
|
||||
|
||||
uninstall:
|
||||
-$(UNINSTALL) "$(DESTDIR)$(bindir)/$(package)"
|
||||
-$(UNINSTALL) "$(DESTDIR)$(mandir)/man1/$(package).1"
|
||||
-$(UNINSTALL) "$(DESTDIR)$(mandir)/man1/$(package).1.gz"
|
||||
-if test -n "$(CATALOGS)"; then \
|
||||
catalogs='$(CATALOGS)'; \
|
||||
for cat in $$catalogs; do \
|
||||
name=`echo $$cat | sed 's,^.*/,,g'`; \
|
||||
if test "`echo $$name | sed 's/.*\(\..*\)/\1/'`" = ".gmo"; then \
|
||||
destdir=$(gnulocaledir); \
|
||||
else \
|
||||
destdir=$(localedir); \
|
||||
fi; \
|
||||
lang=`echo $$name | sed 's/$(CATOBJEXT)$$//'`; \
|
||||
dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \
|
||||
$(UNINSTALL) $$dir/$(PACKAGE)$(INSTOBJEXT); \
|
||||
done; \
|
||||
fi
|
||||
|
||||
release: dist
|
||||
-gpg --list-secret-keys 2>&1 | grep -F 'uid' | grep -Fq "$(MAINTAINER)" && gpg -u "$(MAINTAINER)" -ab *.tar.gz && cp $(package)-$(version).tar.gz.asc $(package)-$(version).tar.gz.txt
|
||||
chmod 644 $(package)-$(version)*
|
||||
@@ -1,46 +0,0 @@
|
||||
#
|
||||
# Variables for Make.
|
||||
#
|
||||
|
||||
srcdir = @srcdir@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
etcdir = @prefix@/etc
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
sbindir = @sbindir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
gnulocaledir = $(prefix)/share/locale
|
||||
|
||||
CATALOGS = @CATALOGS@
|
||||
POFILES = @POFILES@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
MSGFMT = @MSGFMT@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
MSGMERGE = msgmerge
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
|
||||
SHELL = /bin/sh
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
UNINSTALL = rm -f
|
||||
|
||||
LDFLAGS = -r
|
||||
LINKFLAGS = @LDFLAGS@
|
||||
DEFS = @DEFS@ -DLOCALEDIR=\"$(localedir)\"
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/src/include -Isrc/include $(DEFS)
|
||||
LIBS = @LIBS@
|
||||
|
||||
alltarg = @PACKAGE@
|
||||
|
||||
# EOF
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Generate dependencies for a C source file.
|
||||
#
|
||||
|
||||
CC="$1"
|
||||
shift
|
||||
file="$1"
|
||||
shift
|
||||
stem="$1"
|
||||
shift
|
||||
srcdir="$1"
|
||||
abssrc=$(echo "$srcdir" | sed ':1
|
||||
s,^\./,,g
|
||||
t1')
|
||||
shift
|
||||
|
||||
abssrc=$(echo "$abssrc" | sed 's,\.,\\.,g')
|
||||
srcdir=$(echo "$srcdir" | sed 's,\.,\\.,g')
|
||||
|
||||
$CC -M -MG "$@" "$file" \
|
||||
| sed \
|
||||
-e "s,^.*\.o:,${stem}.d ${stem}.o:," \
|
||||
-e 's,'"$srcdir"'/,,g' \
|
||||
-e 's,'"$abssrc"'/,,g' \
|
||||
-e 's, /[^ ]*,,g' \
|
||||
-e '/^ \\$/d' -e 's/ \\$//' \
|
||||
| tr '\n' ' ' \
|
||||
| tr -s ' '
|
||||
|
||||
echo
|
||||
|
||||
# EOF
|
||||
@@ -1,191 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Script to generate an HTML index of all C code from the current directory
|
||||
# downwards (skipping directories ending in ~). The header comment in each
|
||||
# file is listed, and each function's prototype and comment are given. A
|
||||
# list of "TODO:" comments is also generated.
|
||||
#
|
||||
# Outputs the HTML on standard output.
|
||||
#
|
||||
# If a parameter is given, it is the prefix to put before any "view file"
|
||||
# links, eg ".." to link to "../dir/file.c" instead of "dir/file.c".
|
||||
#
|
||||
# Skips any files containing the string !NOINDEX.
|
||||
#
|
||||
# Requires ctags and cproto.
|
||||
#
|
||||
|
||||
command -v "ctags" >/dev/null 2>&1 || { echo "${0##*/}: ctags: command not found" 1>&2; exit 1; }
|
||||
command -v "cproto" >/dev/null 2>&1 || { echo "${0##*/}: cproto: command not found" 1>&2; exit 1; }
|
||||
|
||||
linkPrefix=$1
|
||||
test -n "${linkPrefix}" || linkPrefix="."
|
||||
|
||||
# Add "/" to the link prefix, and empty it entirely if it ends up just "./".
|
||||
linkPrefix=$(echo "${linkPrefix}" | sed 's,/*$,,')
|
||||
test "$linkPrefix" = "." && linkPrefix="" || linkPrefix="${linkPrefix}/"
|
||||
|
||||
# Convert the given string to HTML-escaped values (<, >, & escaped) on
|
||||
# stdout.
|
||||
#
|
||||
html_safe () {
|
||||
echo "$*" \
|
||||
| sed -e 's|&|\&|g;s|<|\<|g;s|>|\>|g'
|
||||
}
|
||||
|
||||
|
||||
# Convert the given string to HTML-escaped values (<, >, & escaped) on
|
||||
# stdout, also adding a <BR> to the end of each line.
|
||||
#
|
||||
html_safebr () {
|
||||
echo "$*" \
|
||||
| sed -e 's|&|\&|g;s|<|\<|g;s|>|\>|g;s/$/<BR>/'
|
||||
}
|
||||
|
||||
allEligibleFiles=$(
|
||||
find . -name '*~' -prune -o -type f -name '*.c' \
|
||||
-exec grep -FL '!NOINDEX' /dev/null '{}' ';'
|
||||
)
|
||||
|
||||
ctagsOutput=$(
|
||||
echo "${allEligibleFiles}" \
|
||||
| ctags -nRf- -L- --c-types=f \
|
||||
| sed 's/ .\// /;s/;" .*$//'
|
||||
)
|
||||
|
||||
sourceFiles=$(echo "${ctagsOutput}" | cut -d ' ' -f 2 | sort | uniq)
|
||||
|
||||
echo '<HTML><HEAD>'
|
||||
echo '<TITLE>Source Code Index</TITLE>'
|
||||
echo '</HEAD><BODY>'
|
||||
echo '<H1><A NAME="top">Source Code Index</A></H1>'
|
||||
echo '<P><UL>'
|
||||
echo '<LI><A HREF="#files">File Listing</A></LI>'
|
||||
echo '<LI><A HREF="#funcs">Function Listing</A></LI>'
|
||||
echo '<LI><A HREF="#todo">To-Do Listing</A></LI>'
|
||||
echo '</UL></P>'
|
||||
|
||||
echo '<H2><A NAME="files">File Listing</A></H2>'
|
||||
echo '<P><UL>'
|
||||
echo "${sourceFiles}" \
|
||||
| sed -e \
|
||||
's|^.*$|<LI><CODE CLASS="filename"><A HREF="#file-\0">\0</A></CODE></LI>|'
|
||||
echo '</UL></P>'
|
||||
|
||||
for sourceFile in ${sourceFiles}; do
|
||||
|
||||
sourceDir="${sourceFile##*/}"
|
||||
test "${sourceDir}" = "${sourceFile}" && sourceDir="."
|
||||
functionPrototypes=$(
|
||||
cproto -f1 -I. -Isrc/include -I"${sourceDir}" "${sourceFile}" 2>/dev/null \
|
||||
| sed -n 's/^.*[ *]\([^ *(]*\)(.*$/\1/p'
|
||||
)
|
||||
fileHeaderComment=$(
|
||||
sed -n -e '1,/\*\//{/\/\*/,/\*\//{s/^[\/ *]//;s/^\*[\/]*//;p;};}' \
|
||||
< "${sourceFile}"
|
||||
)
|
||||
fileShortDescription=$(echo "${fileHeaderComment}" | sed -n '1,/^ *$/{/^ *[^ ]*/p;}')
|
||||
fileLongDescription=$(echo "${fileHeaderComment}" | sed '1,/^ *$/d')
|
||||
|
||||
echo '<P><HR WIDTH="100%"></P>'
|
||||
echo '<P><TABLE BORDER="0"><TR>'
|
||||
echo '<TD VALIGN="TOP"><CODE CLASS="filename">'
|
||||
echo '<A NAME="file-'"${sourceFile}"'">'"${sourceFile}"'</A></CODE></TD>'
|
||||
echo '<TD VALIGN="TOP"> - </TD>'
|
||||
echo '<TD VALIGN="TOP">'"$(html_safe "${fileShortDescription}")"'</TD>'
|
||||
echo '</TR></TABLE></P>'
|
||||
echo '<P><SMALL>[<A HREF="'"${linkPrefix}${sourceFile}"'">View File</A>]</SMALL></P>'
|
||||
echo '<P><BLOCKQUOTE>'
|
||||
html_safebr "${fileLongDescription}"
|
||||
echo '</BLOCKQUOTE></P>'
|
||||
|
||||
if [ -n "${functionPrototypes}" ]; then
|
||||
echo '<P>Functions defined:</P>'
|
||||
echo '<P><UL>'
|
||||
echo "${functionPrototypes}" \
|
||||
| sed 's|^.*$|<A HREF="#func-\0---'"${sourceFile}"'">\0</A>|' \
|
||||
| sed 's/^/<LI><CODE CLASS="funcname">/;s|$|</CODE></LI>|'
|
||||
echo '</UL></P>'
|
||||
fi
|
||||
|
||||
echo '<P ALIGN="RIGHT"><SMALL CLASS="navbar">['
|
||||
echo '<A HREF="#top">Top</A> |'
|
||||
echo '<A HREF="#todo">To Do</A> |'
|
||||
echo '<A HREF="#funcs">Functions</A> ]</SMALL></P>'
|
||||
done
|
||||
|
||||
echo '<H2><A NAME="funcs">Function Listing</A></H2>'
|
||||
echo '<P><UL>'
|
||||
|
||||
echo "${ctagsOutput}" | while read -r functionName sourceFile sourceLineNo restOfLine; do
|
||||
echo '<LI><CODE CLASS="funcname"><A' \
|
||||
'HREF="#func-'"${functionName}"'---'"${sourceFile}"'">'"${functionName}"'</A></CODE>' \
|
||||
'[<CODE CLASS="filename">'"${sourceFile}"'</CODE>]</LI>'
|
||||
done
|
||||
echo '</UL></P>'
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
echo "${ctagsOutput}" | while read -r functionName sourceFile sourceLineNo restOfLine; do
|
||||
|
||||
functionPrototype=$(
|
||||
sed -n "${sourceLineNo},/{/p" < "${sourceFile}" \
|
||||
| tr '\n' ' ' \
|
||||
| tr -d '{'
|
||||
)
|
||||
|
||||
lastCommentOpenLineNo=$(sed -n '1,'"${sourceLineNo}"'{/\/\*/=;}' < "${sourceFile}" | sed -n '$p')
|
||||
test -n "${lastCommentOpenLineNo}" || lastCommentOpenLineNo=1
|
||||
lastCommentCloseLineNo=$(sed -n '1,'"${sourceLineNo}"'{/}/=;}' < "${sourceFile}" | sed -n '$p')
|
||||
test -n "${lastCommentCloseLineNo}" || lastCommentCloseLineNo=1
|
||||
functionHeaderComment=$(
|
||||
sed -n -e \
|
||||
"${lastCommentOpenLineNo},"'/\*\//{h;s/^[\/ *]//;s/^\*[\/]*//;p;x;/\*\//q;}' \
|
||||
< "${sourceFile}"
|
||||
)
|
||||
test "${lastCommentOpenLineNo}" -le "${lastCommentCloseLineNo}" && functionHeaderComment=""
|
||||
|
||||
echo '<P><HR WIDTH="100%"></P>'
|
||||
echo '<P ALIGN="LEFT">'
|
||||
echo '<CODE CLASS="funcname"><A' \
|
||||
'NAME="func-'"${functionName}"'---'"${sourceFile}"'">'"${functionName}"'</A></CODE>' \
|
||||
'[<CODE CLASS="filename"><A HREF="#file-'"${sourceFile}"'">'"${sourceFile}"'</A></CODE>]'
|
||||
echo '</P>'
|
||||
|
||||
echo '<P><CODE CLASS="funcdef">'"$(html_safe "${functionPrototype}")"'</CODE></P>'
|
||||
|
||||
echo '<P><BLOCKQUOTE>'
|
||||
html_safebr "${functionHeaderComment}"
|
||||
echo '</BLOCKQUOTE></P>'
|
||||
|
||||
echo '<P ALIGN="RIGHT"><SMALL CLASS="navbar">['
|
||||
echo '<A HREF="#top">Top</A> |'
|
||||
echo '<A HREF="#todo">To Do</A> |'
|
||||
echo '<A HREF="#files">Files</A> ]</SMALL></P>'
|
||||
done
|
||||
|
||||
echo '<H2><A NAME="todo">To Do Listing</A></H2>'
|
||||
echo '<P><UL>'
|
||||
for sourceFile in ${sourceFiles}; do
|
||||
|
||||
todoLineNumbers=$(sed -n \
|
||||
-e '/\/\*.*\*\//!{/\/\*/,/\*\//{/TODO:/{=;};};}' \
|
||||
-e '/\/\*.*\*\//{/TODO:/{=;};}' \
|
||||
< "${sourceFile}")
|
||||
|
||||
test -n "${todoLineNumbers}" || continue
|
||||
|
||||
echo '<LI><CODE CLASS="filename"><A' \
|
||||
'HREF="#file-'"${sourceFile}"'">'"${sourceFile}"'</A></CODE>'
|
||||
echo '<UL>'
|
||||
|
||||
for todoLineNo in ${todoLineNumbers}; do
|
||||
todoNote=$(sed -n "${todoLineNo}"'{s/^.*TODO://;s/\*\/.*$//;p;}' < "${sourceFile}")
|
||||
echo "<LI>[<B>${todoLineNo}</B>] $(html_safe "${todoNote}")</LI>"
|
||||
done
|
||||
|
||||
echo '</UL></LI>'
|
||||
done
|
||||
|
||||
echo '</BODY></HTML>'
|
||||
|
||||
# EOF
|
||||
@@ -1,541 +0,0 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2020-11-14.01; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# 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
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
# Create dirs (including intermediate dirs) using mode 755.
|
||||
# This is like GNU 'install' as of coreutils 8.32 (2020).
|
||||
mkdir_umask=22
|
||||
|
||||
backupsuffix=
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-p pass -p to $cpprog.
|
||||
-s $stripprog installed files.
|
||||
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
|
||||
By default, rm is invoked with -f; when overridden with RMPROG,
|
||||
it's up to you to specify -f if you want it.
|
||||
|
||||
If -S is not specified, no backups are attempted.
|
||||
|
||||
Email bug reports to bug-automake@gnu.org.
|
||||
Automake home page: https://www.gnu.org/software/automake/
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-p) cpprog="$cpprog -p";;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-S) backupsuffix="$2"
|
||||
shift;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
# Don't chown directories that already exist.
|
||||
if test $dstdir_status = 0; then
|
||||
chowncmd=""
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename.
|
||||
if test -d "$dst"; then
|
||||
if test "$is_target_a_directory" = never; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dstbase=`basename "$src"`
|
||||
case $dst in
|
||||
*/) dst=$dst$dstbase;;
|
||||
*) dst=$dst/$dstbase;;
|
||||
esac
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
case $dstdir in
|
||||
*/) dstdirslash=$dstdir;;
|
||||
*) dstdirslash=$dstdir/;;
|
||||
esac
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
# The $RANDOM variable is not portable (e.g., dash). Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
|
||||
trap '
|
||||
ret=$?
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
|
||||
exit $ret
|
||||
' 0
|
||||
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p'.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=${dstdirslash}_inst.$$_
|
||||
rmtmp=${dstdirslash}_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask &&
|
||||
{ test -z "$stripcmd" || {
|
||||
# Create $dsttmp read-write so that cp doesn't create it read-only,
|
||||
# which would cause strip to fail.
|
||||
if test -z "$doit"; then
|
||||
: >"$dsttmp" # No need to fork-exec 'touch'.
|
||||
else
|
||||
$doit touch "$dsttmp"
|
||||
fi
|
||||
}
|
||||
} &&
|
||||
$doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# If $backupsuffix is set, and the file being installed
|
||||
# already exists, attempt a backup. Don't worry if it fails,
|
||||
# e.g., if mv doesn't support -f.
|
||||
if test -n "$backupsuffix" && test -f "$dst"; then
|
||||
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
@@ -1,130 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Generate Makefile components "filelist.mk~" (list source, object, and
|
||||
# dependency files) and "modules.mk~" (linking rules for each directory's
|
||||
# overall object file) by scanning the directory "src" for files ending in
|
||||
# ".c", and for subdirectories not starting with "_".
|
||||
#
|
||||
# Modules live inside subdirectories called [^_]* - i.e. a directory "foo" will
|
||||
# have a rule created which links all code inside it to "foo.o".
|
||||
#
|
||||
# The directory "src/include" is never scanned; neither are CVS or SVN
|
||||
# directories.
|
||||
#
|
||||
|
||||
listingsFile="$1"
|
||||
linkingRulesFile="$2"
|
||||
|
||||
FIND="find"
|
||||
GREP="grep"
|
||||
command -v gfind 2>/dev/null | grep /gfind >/dev/null && FIND="gfind"
|
||||
command -v which ggrep 2>/dev/null | grep /ggrep >/dev/null && GREP="ggrep"
|
||||
|
||||
{
|
||||
echo '# Automatically generated file listings'
|
||||
echo '#'
|
||||
echo "# Creation time: $(date)"
|
||||
echo
|
||||
} > "${listingsFile}"
|
||||
|
||||
{
|
||||
echo '# Automatically generated module linking rules'
|
||||
echo '#'
|
||||
echo "# Creation time: $(date)"
|
||||
echo
|
||||
} > "${linkingRulesFile}"
|
||||
|
||||
printf "%s" "Scanning for source files: "
|
||||
|
||||
allsrc=$("${FIND}" src -type f -name "*.c" -print)
|
||||
allobj=$(echo "${allsrc}" | tr ' ' '\n' | sed 's/\.c$/.o/')
|
||||
alldep=$(echo "${allsrc}" | tr ' ' '\n' | sed 's/\.c$/.d/')
|
||||
allanalysis=$(echo "${allsrc}" | tr ' ' '\n' | sed 's/\.c$/.e/')
|
||||
|
||||
echo "$(echo "${allsrc}" | wc -w | tr -d ' ') found"
|
||||
|
||||
printf "%s" "Scanning for modules: "
|
||||
|
||||
modules=$("${FIND}" src -type d -print \
|
||||
| "${GREP}" -v '^src$' \
|
||||
| "${GREP}" -v '/_' \
|
||||
| "${GREP}" -v '^src/include' \
|
||||
| "${GREP}" -v 'CVS' \
|
||||
| "${GREP}" -v '.svn' \
|
||||
| while read -r DIR; do \
|
||||
CONTENT=$(/bin/ls -d "${DIR}"/* \
|
||||
| "${GREP}" -v '.po$' \
|
||||
| "${GREP}" -v '.gmo$' \
|
||||
| "${GREP}" -v '.mo$' \
|
||||
| "${GREP}" -v '.h$' \
|
||||
| sed -n '$p'); \
|
||||
[ -n "$CONTENT" ] || continue; \
|
||||
echo "${DIR}"; \
|
||||
done
|
||||
)
|
||||
|
||||
echo "up to $(echo "${modules}" | wc -w | tr -d ' ') found"
|
||||
|
||||
echo "Writing module linking rules"
|
||||
|
||||
printf "%s" "["
|
||||
for i in ${modules}; do printf "%s" " "; done
|
||||
printf "%s\r%s" "]" "["
|
||||
|
||||
for i in ${modules}; do
|
||||
printf "%s" "."
|
||||
allobj="${allobj} ${i}.o"
|
||||
deps=""
|
||||
for j in "${i}"/*.c; do
|
||||
[ -f "$j" ] || continue
|
||||
newobj=$(echo "$j" | sed -e 's@\.c$@.o@')
|
||||
deps="$deps $newobj"
|
||||
done
|
||||
for j in "${i}"/*; do
|
||||
[ -d "$j" ] || continue
|
||||
[ "$(basename "$j")" = "CVS" ] && continue
|
||||
[ "$(basename "$j")" = ".svn" ] && continue
|
||||
CONTENT=$(/bin/ls -d "$j"/* \
|
||||
| "${GREP}" -v '.po$' \
|
||||
| "${GREP}" -v '.gmo$' \
|
||||
| "${GREP}" -v '.mo$' \
|
||||
| "${GREP}" -v '.h$' \
|
||||
| sed -n '$p')
|
||||
[ -n "$CONTENT" ] || continue
|
||||
deps="$deps $j.o"
|
||||
done
|
||||
[ -n "$deps" ] || continue
|
||||
{
|
||||
echo "$i.o: $deps"
|
||||
echo " \$(LD) \$(LDFLAGS) -o \$@ $deps"
|
||||
echo
|
||||
} >> "${linkingRulesFile}"
|
||||
done
|
||||
|
||||
echo ']'
|
||||
|
||||
echo "Listing source, object and dependency files"
|
||||
|
||||
{
|
||||
printf "%s" "allsrc = "
|
||||
echo "$allsrc" | tr '\n' ' ' | sed 's,src/nls/cat-id-tbl.c,,' | sed -e 's/ $//;s/ / \\!/g' \
|
||||
| tr '!' '\n'
|
||||
echo
|
||||
echo
|
||||
printf "%s" "allobj = "
|
||||
echo "$allobj" | tr '\n' ' ' | sed -e 's/ $//;s/ / \\!/g' | tr '!' '\n'
|
||||
echo
|
||||
echo
|
||||
printf "%s" "alldep = "
|
||||
echo "$alldep" | tr '\n' ' ' | sed -e 's/ $//;s/ / \\!/g' | tr '!' '\n'
|
||||
echo
|
||||
echo
|
||||
printf "%s" "allanalysis = "
|
||||
echo "$allanalysis" | tr '\n' ' ' | sed -e 's/ $//;s/ / \\!/g' | tr '!' '\n'
|
||||
echo
|
||||
echo
|
||||
} >> "${listingsFile}"
|
||||
|
||||
echo >> "${linkingRulesFile}"
|
||||
|
||||
# EOF
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Last modified: 1994-03-25
|
||||
# Public domain
|
||||
|
||||
errstatus=0
|
||||
|
||||
for file in ${1+"$@"} ; do
|
||||
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||
shift
|
||||
|
||||
pathcomp=
|
||||
for d in ${1+"$@"} ; do
|
||||
pathcomp="$pathcomp$d"
|
||||
case "$pathcomp" in
|
||||
-* ) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp" 1>&2
|
||||
mkdir "$pathcomp" || errstatus=$?
|
||||
chmod 755 $pathcomp 2>/dev/null
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# mkinstalldirs ends here
|
||||
@@ -1,63 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Messy script to convert all of the given .po files to a single C file on
|
||||
# stdout.
|
||||
|
||||
cat <<EOF
|
||||
/*
|
||||
* Translation table - automatically generated by po2table.sh.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
|
||||
struct msgtable_s {
|
||||
char *msgid;
|
||||
char *msgstr;
|
||||
};
|
||||
|
||||
|
||||
struct msgtable_s *minigettext__gettable(char *lang)
|
||||
{
|
||||
if (0 == lang)
|
||||
return 0;
|
||||
|
||||
EOF
|
||||
|
||||
for POFILE in "$@"; do
|
||||
LANG=$(basename "$POFILE" | sed 's/.po$//')
|
||||
echo " if (strncmp(lang, \"$LANG\", 2) == 0) {"
|
||||
echo " static struct msgtable_s data[] = {";
|
||||
|
||||
awk 'BEGIN{i=0;s=0;}
|
||||
/^msgid[ ]+/ {
|
||||
if (s) print " }, ";
|
||||
print " {";
|
||||
print " " substr($0,7);
|
||||
i=1;
|
||||
s=0;
|
||||
}
|
||||
/^msgstr[ ]+/ {
|
||||
print " ,";
|
||||
i=0;s=1;
|
||||
print " " substr($0,8);
|
||||
}
|
||||
/^[ ]*"/ {
|
||||
if (i||s) print " " $0;
|
||||
}
|
||||
END {if (i||s) print " }\n";}
|
||||
' < "$POFILE"
|
||||
echo ' , { 0, 0 } };'
|
||||
echo " return data;"
|
||||
echo " }"
|
||||
done
|
||||
|
||||
cat <<EOF
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
EOF
|
||||
|
||||
# EOF
|
||||
@@ -1,210 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Parameters: testSubject sourcePath [testScript...]
|
||||
#
|
||||
# Run one or more test scripts. The ${testSubject} is the path of the test
|
||||
# subject program, and the ${sourcePath} is the path to the top level of the
|
||||
# source directory. If any ${testScript} parameters are given, they are the
|
||||
# tests to run (each one being either the full path to a script, or the base
|
||||
# filename of the script in the test directory). If no test scripts are
|
||||
# listed, then all tests directly under "${sourcePath}/tests/" are run.
|
||||
#
|
||||
# Test scripts should be written to exit 0 if the test passed, 2 if the test
|
||||
# is to be skipped, or any other exit status to indicate failure. They are
|
||||
# run via "sh -e", so any command exiting non-zero will cause the test
|
||||
# script to exit early.
|
||||
#
|
||||
# The test scripts can rely on the environment variables "testSubject",
|
||||
# "sourcePath", "workFile1", "workFile2", "workFile3", and "workFile4" being
|
||||
# populated, and should use those work files - which will be present and
|
||||
# empty - for scratch space. They should not delete those files.
|
||||
#
|
||||
# When the test scripts are called, LANG and LC_ALL are set to "C".
|
||||
#
|
||||
# Anything output by a test script on stdout or stderr is captured and shown
|
||||
# after the "OK" / "FAILED" / "skipped" result description.
|
||||
#
|
||||
# The exit status of this script will be 1 if any test failed, 0 otherwise.
|
||||
# A skipped test is not counted as a failure.
|
||||
#
|
||||
|
||||
# Parameters.
|
||||
testSubject="$1"
|
||||
sourcePath="$2"
|
||||
shift
|
||||
shift
|
||||
selectedTests="$*"
|
||||
|
||||
# Constants.
|
||||
formatCodesPass="setaf 2;bold" # terminal capabilities for "pass" formatting
|
||||
formatCodesFail="setaf 1;bold" # terminal capabilities for "fail" formatting
|
||||
formatCodesSkip="setaf 3" # terminal capabilities for "skip" formatting
|
||||
formatCodesZero="setaf 4" # terminal capabilities for zero result
|
||||
|
||||
# Temporary working files, for the test scripts to use.
|
||||
workFile1=$(mktemp 2>/dev/null) || workFile1="./.tmp1"
|
||||
workFile2=$(mktemp 2>/dev/null) || workFile2="./.tmp2"
|
||||
workFile3=$(mktemp 2>/dev/null) || workFile3="./.tmp3"
|
||||
workFile4=$(mktemp 2>/dev/null) || workFile4="./.tmp4"
|
||||
|
||||
# Clean up the temporary files on exit, in case we are interrupted.
|
||||
trap 'rm -f "${workFile1}" "${workFile2}" "${workFile3}" "${workFile4}"' EXIT
|
||||
|
||||
# Variables used by the test scripts.
|
||||
export testSubject sourcePath workFile1 workFile2 workFile3 workFile4
|
||||
|
||||
# Set everything to the "C" locale.
|
||||
LANG=C
|
||||
LC_ALL=C
|
||||
export LANG LC_ALL
|
||||
|
||||
# If no tests were specified, list all test scripts under the source path.
|
||||
test -n "${selectedTests}" || selectedTests=$(find "${sourcePath}/tests" -maxdepth 1 -type f | sort -n)
|
||||
|
||||
# Initial pass to count the number of tests and find the length of the
|
||||
# longest test name, to use when formatting the output.
|
||||
#
|
||||
numberOfTests=0
|
||||
maxTestNameLength=0
|
||||
for testScript in ${selectedTests}; do
|
||||
# Find the test script, make sure it exists.
|
||||
test -f "${testScript}" || testScript="${sourcePath}/tests/${testScript}"
|
||||
test -f "${testScript}" || testScript=$(find "${sourcePath}/tests" -maxdepth 1 -type f -name "${testScript##*/}*" | sed -n '1p')
|
||||
test -f "${testScript}" || continue
|
||||
|
||||
numberOfTests=$((1+numberOfTests))
|
||||
|
||||
testScriptLeaf="${testScript##*/}"
|
||||
testName="$(echo "${testScriptLeaf%.sh}" | tr '_' ' ' | sed 's/ - /: /')"
|
||||
testNameLength=${#testName}
|
||||
test "${testNameLength}" -gt "${maxTestNameLength}" && maxTestNameLength="${testNameLength}"
|
||||
done
|
||||
|
||||
# Set a minimum and maximum test name length.
|
||||
test "${maxTestNameLength}" -lt 10 && maxTestNameLength=10
|
||||
test "${maxTestNameLength}" -gt 60 && maxTestNameLength=60
|
||||
|
||||
# Count the number of digits in the number of tests so we know how wide the
|
||||
# column for the test count should be.
|
||||
testCountWidth=${#numberOfTests}
|
||||
|
||||
# Get the terminal width, for later display formatting calculations.
|
||||
#
|
||||
# We have to fiddle with `stty' because $COLUMNS is only in `bash', `resize`
|
||||
# is not available everywhere, and `stty' itself varies in its output format
|
||||
# between "columns 158" and "158 cols".
|
||||
#
|
||||
terminalWidth=80
|
||||
test -t 1 && terminalWidth=$(stty -a 2>/dev/null | tr ';' '\n' | grep -e cols -e columns | tr ' ' '\n' | grep '[0-9]' | sed -n 1p)
|
||||
test -n "${terminalWidth}" || terminalWidth=80
|
||||
|
||||
# Remaining space left on each line after the result description.
|
||||
colsUsed=$((testCountWidth + 1 + testCountWidth + 2 + maxTestNameLength + 2 + 8 + 2))
|
||||
colsRemaining=0
|
||||
test "${colsUsed}" -lt "${terminalWidth}" && colsRemaining=$((terminalWidth - colsUsed))
|
||||
|
||||
# Run all of the selected test scripts, formatting the output.
|
||||
#
|
||||
testPassCount=0
|
||||
testFailCount=0
|
||||
testSkipCount=0
|
||||
testNumber=0
|
||||
for testScript in ${selectedTests}; do
|
||||
# Find the test script, make sure it exists.
|
||||
test -f "${testScript}" || testScript="${sourcePath}/tests/${testScript}"
|
||||
test -f "${testScript}" || testScript=$(find "${sourcePath}/tests" -maxdepth 1 -type f -name "${testScript##*/}*" | sed -n '1p')
|
||||
test -f "${testScript}" || continue
|
||||
|
||||
testNumber=$((1+testNumber))
|
||||
|
||||
testScriptLeaf="${testScript##*/}"
|
||||
testName="$(echo "${testScriptLeaf%.sh}" | tr '_' ' ' | sed 's/ - /: /')"
|
||||
printf "%${testCountWidth}d/%d: %-${maxTestNameLength}.${maxTestNameLength}s " "${testNumber}" "${numberOfTests}" "${testName}"
|
||||
|
||||
# Run the test script, capturing the output and the exit status.
|
||||
testExitStatus=0
|
||||
testOutput=""
|
||||
if test -s "${testScript}"; then
|
||||
true > "${workFile1}"
|
||||
true > "${workFile2}"
|
||||
true > "${workFile3}"
|
||||
true > "${workFile4}"
|
||||
testOutput=$(sh -e "${testScript}" 2>&1)
|
||||
testExitStatus=$?
|
||||
else
|
||||
testOutput="test script has not yet been written"
|
||||
testExitStatus=2
|
||||
fi
|
||||
|
||||
# Work out what we're going to say about this test result.
|
||||
testResultDescription=""
|
||||
resultFormatCodes=""
|
||||
if test ${testExitStatus} -eq 0; then
|
||||
resultFormatCodes="${formatCodesPass}"
|
||||
testResultDescription="OK"
|
||||
testPassCount=$((1+testPassCount))
|
||||
elif test ${testExitStatus} -eq 2; then
|
||||
resultFormatCodes="${formatCodesSkip}"
|
||||
testResultDescription="skipped"
|
||||
testSkipCount=$((1+testSkipCount))
|
||||
else
|
||||
resultFormatCodes="${formatCodesFail}"
|
||||
testResultDescription="FAILED"
|
||||
testFailCount=$((1+testFailCount))
|
||||
fi
|
||||
|
||||
# If stdout is not a terminal, don't use terminal format codes.
|
||||
test -t 1 || resultFormatCodes=""
|
||||
|
||||
# Show the description of the test result, and start a new line.
|
||||
test -n "${resultFormatCodes}" && command -v tput >/dev/null 2>&1 && echo "${resultFormatCodes}" | tr ';' '\n' | tput -S 2>/dev/null
|
||||
printf "%s" "${testResultDescription}"
|
||||
|
||||
# If there was any output from the test, display it - either on the
|
||||
# current line, if there's space, or the next line, with each line
|
||||
# prefixed with the test number.
|
||||
if test -n "${testOutput}"; then
|
||||
if test "${#testOutput}" -lt "${colsRemaining}" && ! test "$(echo "${testOutput}" | wc -l | tr -dc '0-9')" -gt 1 2>/dev/null; then
|
||||
printf " - %s" "${testOutput}"
|
||||
else
|
||||
printf "\n%s" "$(echo "${testOutput}" | sed "s,^,$(printf "%${testCountWidth}d/%d: - " "${testNumber}" "${numberOfTests}"),")"
|
||||
fi
|
||||
fi
|
||||
printf "\n"
|
||||
|
||||
test -n "${resultFormatCodes}" && command -v tput >/dev/null 2>&1 && tput sgr0 2>/dev/null
|
||||
done
|
||||
|
||||
# Clean up.
|
||||
rm -f "${workFile1}" "${workFile2}" "${workFile3}" "${workFile4}"
|
||||
trap '' EXIT
|
||||
|
||||
# Report the totals.
|
||||
printf "\n"
|
||||
printf "%s: " "Tests passed"
|
||||
numberFormatting="${formatCodesPass}"
|
||||
test "${testPassCount}" -gt 0 || numberFormatting="${formatCodesZero}"
|
||||
test -t 1 && command -v tput >/dev/null 2>&1 && echo "${numberFormatting}" | tr ';' '\n' | tput -S 2>/dev/null
|
||||
printf "%d" "${testPassCount}"
|
||||
test -t 1 && command -v tput >/dev/null 2>&1 && tput sgr0 2>/dev/null
|
||||
|
||||
printf " %s: " "Tests failed"
|
||||
numberFormatting="${formatCodesFail}"
|
||||
test "${testFailCount}" -gt 0 || numberFormatting="${formatCodesZero}"
|
||||
test -t 1 && command -v tput >/dev/null 2>&1 && echo "${numberFormatting}" | tr ';' '\n' | tput -S 2>/dev/null
|
||||
printf "%d" "${testFailCount}"
|
||||
test -t 1 && command -v tput >/dev/null 2>&1 && tput sgr0 2>/dev/null
|
||||
|
||||
printf " %s: " "Tests skipped"
|
||||
numberFormatting="${formatCodesSkip}"
|
||||
test "${testSkipCount}" -gt 0 || numberFormatting="${formatCodesZero}"
|
||||
test -t 1 && command -v tput >/dev/null 2>&1 && echo "${numberFormatting}" | tr ';' '\n' | tput -S 2>/dev/null
|
||||
printf "%d" "${testSkipCount}"
|
||||
test -t 1 && command -v tput >/dev/null 2>&1 && tput sgr0 2>/dev/null
|
||||
printf "\n"
|
||||
|
||||
# Exit with status 1 if any test failed outright, 0 otherwise.
|
||||
test "${testFailCount}" -eq 0 || exit 1
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl
|
||||
dnl Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
dnl
|
||||
dnl License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
|
||||
AC_INIT([pv], [1.11.0], [https://codeberg.org/ivarch/pv/issues], [pv], [https://ivarch.com/p/pv])
|
||||
AC_CONFIG_SRCDIR([src/include/config.h.in])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([src/include/config.h])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
||||
AC_LANG(C)
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_C_CONST
|
||||
AC_HEADER_STDBOOL
|
||||
AC_SYS_LARGEFILE
|
||||
AM_GNU_GETTEXT_VERSION([0.21])
|
||||
AM_GNU_GETTEXT_REQUIRE_VERSION([0.21])
|
||||
AM_GNU_GETTEXT([external])
|
||||
if test "$USE_NLS" = "yes"; then
|
||||
CPPFLAGS="$CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\""
|
||||
LIBS="$LIBS $LIBINTL"
|
||||
fi
|
||||
|
||||
dnl Items we can use if present, but can do without if not present.
|
||||
AC_CHECK_FUNCS([getopt_long])
|
||||
AC_CHECK_FUNCS([vsnprintf vasprintf strlcat strtoul memrchr])
|
||||
AC_CHECK_FUNCS([fdatasync])
|
||||
AC_CHECK_FUNCS([fpathconf sysconf posix_memalign posix_fadvise])
|
||||
AC_CHECK_FUNCS([getcwd])
|
||||
AC_CHECK_FUNCS([nanosleep])
|
||||
AC_CHECK_FUNCS([setitimer])
|
||||
AC_CHECK_FUNCS([setproctitle])
|
||||
AC_CHECK_FUNCS([nftw])
|
||||
AC_CHECK_FUNCS([strsignal])
|
||||
AC_CHECK_HEADERS([getopt.h])
|
||||
AC_CHECK_HEADERS([limits.h])
|
||||
AC_CHECK_HEADERS([langinfo.h])
|
||||
AC_CHECK_HEADERS([wctype.h])
|
||||
AC_CHECK_HEADERS([termios.h])
|
||||
AC_CHECK_HEADERS([libgen.h])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h])
|
||||
AC_CHECK_HEADERS([libintl.h locale.h])
|
||||
AC_CHECK_HEADERS([sys/sysmacros.h])
|
||||
AC_CHECK_HEADERS([ftw.h])
|
||||
AC_CHECK_HEADERS([poll.h sys/poll.h])
|
||||
AC_CHECK_FUNCS([poll])
|
||||
AC_CHECK_MEMBERS([struct stat.st_blksize])
|
||||
AC_CHECK_DECLS([SA_SIGINFO], [], [], [[#include <signal.h>]])
|
||||
|
||||
AC_SEARCH_LIBS([sqrtl],[m])
|
||||
AC_SEARCH_LIBS([fmod],[m])
|
||||
AC_SEARCH_LIBS([lroundl],[m])
|
||||
AC_CHECK_HEADERS([math.h])
|
||||
AC_CHECK_FUNCS([sqrtl])
|
||||
AC_CHECK_FUNCS([fmod])
|
||||
AC_CHECK_FUNCS([lroundl])
|
||||
|
||||
dnl Libraries that may contain key functions.
|
||||
AC_SEARCH_LIBS([clock_gettime],[rt])
|
||||
|
||||
dnl Items we can't do without.
|
||||
AC_CHECK_FUNCS([alarm basename clock_gettime dup2 memcpy memmove memset mkdir select setlocale strchr strerror strrchr strstr], [], [AC_MSG_ERROR([required function is missing])])
|
||||
AC_CHECK_HEADERS([fcntl.h sys/file.h sys/time.h unistd.h], [], [AC_MSG_ERROR([required header file is missing])])
|
||||
|
||||
dnl Make sure all the types we use are defined.
|
||||
AC_TYPE_INT32_T
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UID_T
|
||||
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
|
||||
dnl Check whether a signal handler can see the PID of the sender.
|
||||
AC_MSG_CHECKING([siginfo_t provides a signal sender's PID])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([[
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static pid_t signalSender = 0;
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
static void receiveUSR2( __attribute__((unused))
|
||||
int sig, siginfo_t * info, __attribute__((unused))
|
||||
void *ucontext)
|
||||
{
|
||||
if (NULL != info)
|
||||
signalSender = info->si_pid;
|
||||
}
|
||||
#endif
|
||||
]], [[
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
#ifdef SA_SIGINFO
|
||||
sa.sa_sigaction = receiveUSR2;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
(void) sigaction(SIGUSR2, &sa, NULL);
|
||||
raise(SIGUSR2);
|
||||
#endif
|
||||
return signalSender < 1 ? 1 : 0;
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([SIGINFO_PROVIDES_PID], [1], [Signal handlers can determine the sending PID])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
], [
|
||||
AC_MSG_RESULT([cannot check, assuming yes])
|
||||
AC_DEFINE([SIGINFO_PROVIDES_PID], [1], [Signal handlers can determine the sending PID])
|
||||
]
|
||||
)
|
||||
|
||||
AH_BOTTOM([#include "config-aux.h"])
|
||||
|
||||
AC_ARG_ENABLE([debugging],
|
||||
[AS_HELP_STRING([--enable-debugging], [compile with debugging support])],
|
||||
if test "$enable_debugging" = "yes"; then
|
||||
CFLAGS="$CFLAGS -g -Wall"
|
||||
AC_DEFINE([ENABLE_DEBUGGING], [1], [Debugging support enabled])
|
||||
fi
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE([profiling],
|
||||
[AS_HELP_STRING([--enable-profiling], [compile with profiling support])],
|
||||
if test "$enable_profiling" = "yes"; then
|
||||
CFLAGS="-pg $CFLAGS"
|
||||
fi
|
||||
)
|
||||
|
||||
SPLICE_SUPPORT="no"
|
||||
AC_ARG_ENABLE([splice],
|
||||
[AS_HELP_STRING([--disable-splice], [do not use splice system call])],
|
||||
if test "$enable_splice" = "yes"; then
|
||||
SPLICE_SUPPORT="yes"
|
||||
fi,
|
||||
SPLICE_SUPPORT="yes"
|
||||
)
|
||||
|
||||
COPY_FILE_RANGE_SUPPORT="no"
|
||||
AC_ARG_ENABLE([copy-file-range],
|
||||
[AS_HELP_STRING([--disable-copy-file-range], [do not use copy_file_range system call])],
|
||||
if test "$enable_copy_file_range" = "yes"; then
|
||||
COPY_FILE_RANGE_SUPPORT="yes"
|
||||
fi,
|
||||
COPY_FILE_RANGE_SUPPORT="yes"
|
||||
)
|
||||
|
||||
IPC_SUPPORT="no"
|
||||
AC_ARG_ENABLE([ipc],
|
||||
[AS_HELP_STRING([--disable-ipc], [turn off IPC messaging])],
|
||||
if test "$enable_ipc" = "yes"; then
|
||||
IPC_SUPPORT="yes"
|
||||
fi,
|
||||
IPC_SUPPORT="yes"
|
||||
)
|
||||
|
||||
AC_ARG_WITH([ncurses],
|
||||
[AS_HELP_STRING([--without-ncurses], [disable the use of ncurses for terminal info])],
|
||||
[],
|
||||
[with_curses=yes])
|
||||
AS_IF([test "x$with_ncurses" != xno],
|
||||
[
|
||||
AC_SEARCH_LIBS([tigetnum],[tinfo ncurses], [
|
||||
AC_CHECK_HEADERS([term.h],[
|
||||
AC_DEFINE([ENABLE_NCURSES], [1], [Build with ncurses support])
|
||||
])
|
||||
], [])
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([static],
|
||||
[AS_HELP_STRING([--enable-static], [enable static linking])],
|
||||
[
|
||||
if test "$enable_static" = "yes"; then
|
||||
CFLAGS="$CFLAGS -static"
|
||||
fi
|
||||
])
|
||||
|
||||
dnl AIX needs -lc128
|
||||
AC_EGREP_CPP([^yes$], [#ifdef _AIX
|
||||
yes
|
||||
#endif
|
||||
], [LIBS="$LIBS -lc128"])
|
||||
|
||||
if test "$IPC_SUPPORT" = "yes"; then
|
||||
AC_CHECK_HEADERS([sys/ipc.h], [], [IPC_SUPPORT=no])
|
||||
AC_CHECK_HEADERS([sys/shm.h], [], [IPC_SUPPORT=no])
|
||||
AC_CHECK_HEADERS([sys/param.h])
|
||||
if test "$IPC_SUPPORT" = "yes"; then
|
||||
AC_CHECK_FUNCS([shmget], [], [IPC_SUPPORT=no])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$IPC_SUPPORT" = "yes"; then
|
||||
AC_DEFINE([HAVE_IPC], [1], [IPC support enabled])
|
||||
fi
|
||||
|
||||
if test "$SPLICE_SUPPORT" = "yes"; then
|
||||
AC_CHECK_FUNCS([splice])
|
||||
fi
|
||||
|
||||
if test "$COPY_FILE_RANGE_SUPPORT" = "yes"; then
|
||||
AC_CHECK_FUNCS([copy_file_range])
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/src/include"
|
||||
|
||||
dnl This must go after all the compiler based tests above.
|
||||
AC_LANG_WERROR
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
po/Makefile.in
|
||||
Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
@@ -1,87 +0,0 @@
|
||||
The following people have contributed to this project, and their assistance
|
||||
is acknowledged and greatly appreciated:
|
||||
|
||||
* Antoine Beaupré <anarcat@debian.org> - Debian package maintainer
|
||||
* Kevin Coyner <kcoyner@debian.org> - previous Debian package maintainer
|
||||
* Cédric Delfosse <cedric@debian.org> - previous Debian package maintainer
|
||||
* Jakub Hrozek <jhrozek@redhat.com> - Fedora package maintainer
|
||||
* Eduardo Aguiar <eduardo.oliveira@sondabrasil.com.br> - provided Portuguese (Brazilian) translation
|
||||
* Stéphane Lacasse <stephane@gorfou.ca> - provided French translation
|
||||
* Marcos Kreinacke <public@kreinacke.com> - provided German translation
|
||||
* Bartosz Feński <fenio@o2.pl> <http://skawina.eu.org/> - provided Polish translation along with Krystian Zubel
|
||||
* Joshua Jensen - reported RPM installation bug
|
||||
* Boris Folgmann <http://www.folgmann.com/en/> - reported cursor handling bug
|
||||
* Mathias Gumz - reported NLS bug
|
||||
* Daniel Roethlisberger - submitted patch to use lockfiles for "`-c`" if terminal locking fails
|
||||
* Adam Buchbinder - lots of help with a Cygwin port of "`-c`"
|
||||
* Mark Tomich <http://metuchen.dyndns.org> - suggested "`-B`" option
|
||||
* Gert Menke - reported bug when piping to `dd` with a large input buffer size
|
||||
* Ville Herva <Ville.Herva@iki.fi> - informative bug report about rate limiting performance
|
||||
* Elias Pipping - patch to compile properly on Darwin 9; potential NULL deref report
|
||||
* Patrick Collison - similar patch for OS X
|
||||
* Boris Lohner - reported problem that "`-L`" does not complain if given non-numeric value
|
||||
* Sebastian Kayser - supplied testing for *SIGPIPE*, demonstrated internationalisation problem
|
||||
* Laszlo Ersek <http://phptest11.atw.hu/> - reported shared memory leak on *SIGINT* with "`-c`"
|
||||
* Phil Rutschman <http://bandgap.rsnsoft.com/> - provided a patch for fully restoring terminal state on exit
|
||||
* Henry Precheur <http://henry.precheur.org/> - reporting and suggestions for "`--rate-limit`" bug when rate is under 10
|
||||
* E. Rosten <http://mi.eng.cam.ac.uk/~er258/> - supplied patch for block buffering in line mode
|
||||
* Kjetil Torgrim Homme - reported compilation error with default *CFLAGS* on non-GCC compilers
|
||||
* Alexandre de Verteuil - reported bug in OS X build and supplied test environment to fix in
|
||||
* Martin Baum - supplied patch to return nonzero exit status if terminated by signal
|
||||
* Sam Nelson <http://www.siliconfuture.net/> - supplied patch to fix trailing slash on *DESTDIR*
|
||||
* Daniel Pape - reported Cygwin installation problem due to *DESTDIR*
|
||||
* Philipp Beckers - ported to the Syabas PopcornHour A-100 series
|
||||
* Henry Gebhard <hsggebhardt@googlemail.com> - supplied patches to improve SI prefixes and add "`--average-rate`"
|
||||
* Vladimir Kokarev, Alexander Leo - reported that exit status did not reflect file errors
|
||||
* Thomas Rachel - submitted patches for IEEE1541 (MiB suffixes), 1+e03 bug
|
||||
* Guillaume Marcais - submitted speedup patch for line mode
|
||||
* Moritz Barsnick - submitted patch for compile warning in size calculation
|
||||
* Pawel Piatek - submitted RPM and patches for AIX
|
||||
* Sami Liedes - submitted patch for "`--timer`" and "`--bytes`" with "`--numeric`"
|
||||
* Steven Willis - reported problem with "`-R`" killing non-PV remote processes
|
||||
* Vladimir Pal, Vladimir Ermakov - submitted patch which led to development of "`--format`" option
|
||||
* Peter Samuelson <peter@p12n.org> - submitted patch to calculate size if stdout is a block device
|
||||
* Miguel Diaz - much Cygwin help (and packaging), found narrow-terminal bug
|
||||
* Jim Salter <http://ubuntuwiki.net> - commissioned work on the "`--skip-errors`" option
|
||||
* Wouter Pronk - reported build problem on SCO
|
||||
* Bryan Dongray <http://www.dongrays.com> - provided patches for test scripts failing on older Red Hats
|
||||
* Zev Weiss <www.bewilderbeest.net> - provided patch to fix `splice()` not using stdin
|
||||
* Zing Shishak - provided patch for "`--null`" / "`-0`" (count null terminated lines)
|
||||
* Jacek Wielemborek <http://deetah.jogger.pl/kategorie/english> - implemented fdwatch in Python, suggested PV port; reported bug with "`-l`" and ETA / size; many other contributions
|
||||
* Kim Krecht - suggested buffer fill status and last bytes output display options
|
||||
* Cristian Ciupitu <http://ciupicri.github.io>, Josh Stone - pointed out file descriptor leak with helpful suggestions (Josh Stone initially noticed the missing close)
|
||||
* Jan Seda - found issue with `splice()` and *SPLICE_F_NONBLOCK* causing slowdown
|
||||
* André Stapf - pointed out formatting problem e.g. 13GB -> 13.1GB which should be shown 13.0GB -> 13.1GB; highlighted on-startup row swapping in "`-c`"
|
||||
* Damon Harper <http://www.usrbin.ca/> - suggested "`-D`" / "`--delay-start`" option
|
||||
* Ganaël Laplanche <http://www.martymac.org> - provided patch for `lstat64()` on systems that do not support it
|
||||
* Peter Korsgaard <http://www.buildroot.net/> - provided similar patch for `lstat64()`, specifically for uClibc support; provided AIX cross-compilation patch to fix bug in "`-lc128`" check
|
||||
* Ralf Ramsauer <https://blog.ramses-pyramidenbau.de/> - reported bug which dropped transfer rate on terminal resize
|
||||
* Michiel Van Herwegen - reported and discussed bug with "`-l`" and ETA / size
|
||||
* Erkki Seppälä <http://www.inside.org/~flux/> - provided patch implementing "`-I`"
|
||||
* Eric A. Borisch - provided details of compatibility fix for "`%Lu`" in watchpid code
|
||||
* Jan Venekamp - reported MacOS buffer size interactions with pipes
|
||||
* Matt <https://github.com/lemonsqueeze/pv> - provided "rate-window" patches for rate calculation
|
||||
* [Filippo Valsorda](https://github.com/FiloSottile) - provided patch for stat64 issue on Apple Silicon
|
||||
* Matt Koscica, William Dillon - also reported stat64 issue on Apple Silicon
|
||||
* [Demitri Muna](https://github.com/demitri) - assisted with stat64 patch on Apple Silicon
|
||||
* Norman Rasmussen - suggested "`-c`" with "`-d PID:FD`", reject "`-N`" with "`-d PID`"
|
||||
* Andriy Gapon, Jonathan Elchison - reported bug where "`pv /dev/zero >/dev/null &`" stops immediately
|
||||
* Marcelo Chiesa - reported unused-result warnings when compiling PV 1.6.6
|
||||
* Jered Floyd - provided patches to improve "`--rate-limit`"
|
||||
* Christoph Biedl - provided ETA and dynamic interval patches
|
||||
* Richard Fonfara - provided German translations for "`pv --help`"
|
||||
* Johannes Gerer <http://johannesgerer.com> - suggested that "`-B`" should enable "`-C`"
|
||||
* Sam James - provided fix for number.c build issue caused by missing stddef.h
|
||||
* Jakub Wilk <jwilk@jwilk.net> - corrected README encoding
|
||||
* Frederik Eaton - reported issue with `<()` shell constructs
|
||||
* [gray](https://github.com/gray) - reported issue with "`--force`" and terminal process groups, and proposed a patch
|
||||
* [Luc Gommans](https://github.com/lgommans) / https://lgms.nl/ - provided a "momentary ETA" patch
|
||||
* [ikasty](https://github.com/ikasty) - added relative filename display to "`--watchfd`"
|
||||
* [Michael Weiß](https://github.com/quitschbo) - corrected behaviour when not attached to a terminal
|
||||
* [christoph-zededa](https://github.com/christoph-zededa) - provided OS X support for "`--watchfd`"
|
||||
* [Dave Beckett](https://github.com/dajobe) - added "`@filename`" syntax to "`--size`", and corrected an autoconf problem with stat64 on OS X
|
||||
* [Volodymyr Bychkovyak](https://github.com/vbychkoviak) - provided fix for rate limit behaviour with bursty traffic
|
||||
* [Nick Black](https://nick-black.com) - added "`--bits`" option
|
||||
* [Andrew Schulman](https://github.com/andrew-schulman) - provided reproducible example of terminal size detection issue in 1.7.17/1.7.18
|
||||
|
||||
---
|
||||
-171
@@ -1,171 +0,0 @@
|
||||
This package is free software, and is being distributed under the terms
|
||||
of the Artistic License 2.0.
|
||||
|
||||
----------------------------------------------------------
|
||||
|
||||
Artistic License 2.0
|
||||
|
||||
Copyright (c) 2000-2006, The Perl Foundation.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed. Preamble
|
||||
|
||||
This license establishes the terms under which a given free software
|
||||
Package may be copied, modified, distributed, and/or redistributed. The
|
||||
intent is that the Copyright Holder maintains some artistic control
|
||||
over the development of that Package while still keeping the Package
|
||||
available as open source and free software.
|
||||
|
||||
You are always permitted to make arrangements wholly outside of this
|
||||
license directly with the Copyright Holder of a given Package. If the
|
||||
terms of this license do not permit the full use that you propose to
|
||||
make of the Package, you should contact the Copyright Holder and seek
|
||||
a different licensing arrangement. Definitions
|
||||
|
||||
"Copyright Holder" means the individual(s) or organization(s) named in
|
||||
the copyright notice for the entire Package.
|
||||
|
||||
"Contributor" means any party that has contributed code or other material
|
||||
to the Package, in accordance with the Copyright Holder's procedures.
|
||||
|
||||
"You" and "your" means any person who would like to copy, distribute,
|
||||
or modify the Package.
|
||||
|
||||
"Package" means the collection of files distributed by the Copyright
|
||||
Holder, and derivatives of that collection and/or of those files. A given
|
||||
Package may consist of either the Standard Version, or a Modified Version.
|
||||
|
||||
"Distribute" means providing a copy of the Package or making it accessible
|
||||
to anyone else, or in the case of a company or organization, to others
|
||||
outside of your company or organization.
|
||||
|
||||
"Distributor Fee" means any fee that you charge for Distributing this
|
||||
Package or providing support for this Package to another party. It does
|
||||
not mean licensing fees.
|
||||
|
||||
"Standard Version" refers to the Package if it has not been modified,
|
||||
or has been modified only in ways explicitly requested by the Copyright
|
||||
Holder.
|
||||
|
||||
"Modified Version" means the Package, if it has been changed, and such
|
||||
changes were not explicitly requested by the Copyright Holder.
|
||||
|
||||
"Original License" means this Artistic License as Distributed with the
|
||||
Standard Version of the Package, in its current version or as it may be
|
||||
modified by The Perl Foundation in the future.
|
||||
|
||||
"Source" form means the source code, documentation source, and
|
||||
configuration files for the Package.
|
||||
|
||||
"Compiled" form means the compiled bytecode, object code, binary, or any
|
||||
other form resulting from mechanical transformation or translation of
|
||||
the Source form. Permission for Use and Modification Without Distribution
|
||||
|
||||
(1) You are permitted to use the Standard Version and create and use
|
||||
Modified Versions for any purpose without restriction, provided that you
|
||||
do not Distribute the Modified Version. Permissions for Redistribution
|
||||
of the Standard Version
|
||||
|
||||
(2) You may Distribute verbatim copies of the Source form of the Standard
|
||||
Version of this Package in any medium without restriction, either gratis
|
||||
or for a Distributor Fee, provided that you duplicate all of the original
|
||||
copyright notices and associated disclaimers. At your discretion, such
|
||||
verbatim copies may or may not include a Compiled form of the Package.
|
||||
|
||||
(3) You may apply any bug fixes, portability changes, and other
|
||||
modifications made available from the Copyright Holder. The resulting
|
||||
Package will still be considered the Standard Version, and as such will
|
||||
be subject to the Original License. Distribution of Modified Versions
|
||||
of the Package as Source
|
||||
|
||||
(4) You may Distribute your Modified Version as Source (either gratis
|
||||
or for a Distributor Fee, and with or without a Compiled form of the
|
||||
Modified Version) provided that you clearly document how it differs
|
||||
from the Standard Version, including, but not limited to, documenting
|
||||
any non-standard features, executables, or modules, and provided that
|
||||
you do at least ONE of the following:
|
||||
|
||||
(a) make the Modified Version available to the Copyright Holder of the
|
||||
Standard Version, under the Original License, so that the Copyright Holder
|
||||
may include your modifications in the Standard Version.
|
||||
(b) ensure that installation of your Modified Version does not prevent the
|
||||
user installing or running the Standard Version. In addition, the Modified
|
||||
Version must bear a name that is different from the name of the Standard
|
||||
Version.
|
||||
(c) allow anyone who receives a copy of the Modified Version to make
|
||||
the Source form of the Modified Version available to others under
|
||||
(i) the Original License or
|
||||
(ii) a license that permits the licensee to freely copy, modify and
|
||||
redistribute the Modified Version using the same licensing terms that apply
|
||||
to the copy that the licensee received, and requires that the Source form of
|
||||
the Modified Version, and of any works derived from it, be made freely
|
||||
available in that license fees are prohibited but Distributor Fees are
|
||||
allowed. Distribution of Compiled Forms of the Standard Version or Modified
|
||||
Versions without the Source
|
||||
|
||||
(5) You may Distribute Compiled forms of the Standard Version without
|
||||
the Source, provided that you include complete instructions on how to
|
||||
get the Source of the Standard Version. Such instructions must be valid
|
||||
at the time of your distribution. If these instructions, at any time
|
||||
while you are carrying out such distribution, become invalid, you must
|
||||
provide new instructions on demand or cease further distribution. If
|
||||
you provide valid instructions or cease distribution within thirty days
|
||||
after you become aware that the instructions are invalid, then you do
|
||||
not forfeit any of your rights under this license.
|
||||
|
||||
(6) You may Distribute a Modified Version in Compiled form without the
|
||||
Source, provided that you comply with Section 4 with respect to the
|
||||
Source of the Modified Version. Aggregating or Linking the Package
|
||||
|
||||
(7) You may aggregate the Package (either the Standard Version or
|
||||
Modified Version) with other packages and Distribute the resulting
|
||||
aggregation provided that you do not charge a licensing fee for the
|
||||
Package. Distributor Fees are permitted, and licensing fees for other
|
||||
components in the aggregation are permitted. The terms of this license
|
||||
apply to the use and Distribution of the Standard or Modified Versions
|
||||
as included in the aggregation.
|
||||
|
||||
(8) You are permitted to link Modified and Standard Versions with other
|
||||
works, to embed the Package in a larger work of your own, or to build
|
||||
stand-alone binary or bytecode versions of applications that include the
|
||||
Package, and Distribute the result without restriction, provided the
|
||||
result does not expose a direct interface to the Package. Items That
|
||||
are Not Considered Part of a Modified Version
|
||||
|
||||
(9) Works (including, but not limited to, modules and scripts) that
|
||||
merely extend or make use of the Package, do not, by themselves, cause
|
||||
the Package to be a Modified Version. In addition, such works are not
|
||||
considered parts of the Package itself, and are not subject to the terms
|
||||
of this license. General Provisions
|
||||
|
||||
(10) Any use, modification, and distribution of the Standard or Modified
|
||||
Versions is governed by this Artistic License. By using, modifying or
|
||||
distributing the Package, you accept this license. Do not use, modify,
|
||||
or distribute the Package, if you do not accept this license.
|
||||
|
||||
(11) If your Modified Version has been derived from a Modified Version
|
||||
made by someone other than you, you are nevertheless required to ensure
|
||||
that your Modified Version complies with the requirements of this license.
|
||||
|
||||
(12) This license does not grant you the right to use any trademark,
|
||||
service mark, tradename, or logo of the Copyright Holder.
|
||||
|
||||
(13) This license includes the non-exclusive, worldwide, free-of-charge
|
||||
patent license to make, have made, use, offer to sell, sell, import
|
||||
and otherwise transfer the Package with respect to any patent claims
|
||||
licensable by the Copyright Holder that are necessarily infringed by the
|
||||
Package. If you institute patent litigation (including a cross-claim or
|
||||
counterclaim) against any party alleging that the Package constitutes
|
||||
direct or contributory patent infringement, then this Artistic License
|
||||
to you shall terminate on the date that such litigation is filed.
|
||||
|
||||
(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT
|
||||
HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT
|
||||
PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER
|
||||
OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
|
||||
CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------
|
||||
@@ -1,125 +0,0 @@
|
||||
Notes for developers and translators
|
||||
====================================
|
||||
|
||||
The following "`configure`" options will be of interest to developers and
|
||||
translators:
|
||||
|
||||
* `--enable-debugging` - build in debugging support
|
||||
* `--enable-profiling` - build in support for profiling
|
||||
* `--enable-static-nls` - compile translations directly into the program
|
||||
|
||||
These "`make`" targets are available:
|
||||
|
||||
* `make help` - describe all of the "`.PHONY`" targets
|
||||
* `make index` - generate a source code index
|
||||
* `make analyse` - run _splint_ and _flawfinder_ on all C source files
|
||||
|
||||
|
||||
Debugging and profiling support
|
||||
-------------------------------
|
||||
|
||||
When "`./configure --enable-debugging`" is used, the "`pv`" produced by
|
||||
"`make`" will support an extra option, "`--debug FILE`", which will cause
|
||||
debugging output to be written to *FILE*. This is not recommended for
|
||||
production builds due to the extra processing it introduces, and the
|
||||
potential size of the output.
|
||||
|
||||
Within the code, "`debug()`" is used in a similar way to "`printf()`". It
|
||||
will automatically include the calling function, source file, and line
|
||||
number, so they don't need to be included in the parameters. When debugging
|
||||
support is not enabled, it evaluates to a null statement.
|
||||
|
||||
This does mean that if you call "`debug()`", make sure it has no side
|
||||
effects, as they won't be present in builds without debugging support.
|
||||
|
||||
Builds produced after "`./configure --enable-profiling`" will write profile
|
||||
data when run, to be used with _gprof_. See "`man gprof`" for details.
|
||||
|
||||
|
||||
Source code indexing
|
||||
--------------------
|
||||
|
||||
Running "`make index`" calls a script which uses _cproto_ and _ctags_ to
|
||||
generate a single file, "`index.html`", which lists all C source files, all
|
||||
functions within them, and all TODOs marked in the code.
|
||||
|
||||
It relies on each function having a comment block directly before it,
|
||||
describing what it does.
|
||||
|
||||
The indexing script pre-dates the author's knowledge of documentation
|
||||
generation tools like Doxygen, and is over 20 years old. If it contains
|
||||
bugs, then rather than fixing them, it may be worth looking at how to alter
|
||||
the C sources to better suit widely available documentation generation
|
||||
tools. Please open issues or start discussions about this if it comes up.
|
||||
|
||||
|
||||
Source code analysis
|
||||
--------------------
|
||||
|
||||
Running "`make analyse`" runs _splint_ and _flawfinder_ on all C sources,
|
||||
writing the output of both programs to files named "`*.e`" for each "`*.c`".
|
||||
|
||||
There are no dependency rules set up for these "`.e`" files, so if a header
|
||||
file is altered, either run "`make analysisclean`", manually remove the
|
||||
relevant "`.e`" files, or update the timestamp of the relevant "`.c`" files
|
||||
before running "`make analyse`" again.
|
||||
|
||||
The eventual goal is for all C source files to generate zero warnings from
|
||||
either tool.
|
||||
|
||||
|
||||
Translation notes
|
||||
-----------------
|
||||
|
||||
The message catalogues used to translate program messages into other
|
||||
languages are in the "`src/nls/`" directory, named "`xx.po`", where "`xx`"
|
||||
is the ISO 639-1 2-letter language code, such as "`fr`" for French.
|
||||
|
||||
Each of these files contains lines like this:
|
||||
|
||||
#: src/pv/cursor.c:85
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "erro ao ler o nome do terminal"
|
||||
|
||||
The comment line, starting "`#`", shows the source filename and line number
|
||||
at which this message can be found. The "`msgid`" is the original message
|
||||
in the program, in English. The "`msgstr`" is the translated text.
|
||||
|
||||
It is the "`msgstr`" lines which need to be updated by translators.
|
||||
|
||||
Message catalogue files should all be encoded as UTF-8.
|
||||
|
||||
To quickly test translations, use "`./configure --enable-static-nls`". This
|
||||
is not recommended for production use, because it replaces the system
|
||||
internationalisation libraries with some very simplistic alternatives, but
|
||||
it has the benefit of compiling the message catalogues directly into the
|
||||
program.
|
||||
|
||||
This means that after making a change to a "`.po`" file, do this:
|
||||
|
||||
make
|
||||
LANG=de LC_ALL=en_GB.UTF-8 ./pv --help
|
||||
|
||||
Replace "`--help`" with whatever is appropriate for your test. In this
|
||||
example, the language being tested is "`de`" (German), on a system which is
|
||||
otherwise running in English with UTF-8 support.
|
||||
|
||||
To add a new language, edit "`autoconf/configure.in`". Look for this line:
|
||||
|
||||
for lang in de fr pl pt; do
|
||||
|
||||
Add the new language code before the "`; do`".
|
||||
|
||||
Create the new message catalogue file under "`src/nls/`" by copying
|
||||
"`src/nls/pv.pot`" to "`src/nls/xx.po`", where "`xx`" is the language code,
|
||||
and adjusting it.
|
||||
|
||||
Then run "`./generate.sh`" to generate a new "`configure`" script; you will
|
||||
need to run "`./configure --enable-static-nls`" and "`make`" afterwards.
|
||||
|
||||
When the source code is updated, running "`make`" will update the "`pv.pot`"
|
||||
file so that it lists where all the messages are in the source, and running
|
||||
"`make update-po`" will use _msgmerge_ to update all of the "`.po`" files
|
||||
from the updated "`pv.pot`" file. After doing this, look for missing
|
||||
translations (empty "`msgstr`" lines) or translations marked as "fuzzy", as
|
||||
these will need to be corrected by translators.
|
||||
-425
@@ -1,425 +0,0 @@
|
||||
1.7.24 - 30 July 2023
|
||||
|
||||
* fix: correct terminal size detection, broken in 1.7.17 by the configuration script rewrite ([GH#72](https://github.com/a-j-wood/pv/issues/72))
|
||||
* security: removed *DEBUG* environment variable in debug mode, added "`--debug`" instead
|
||||
* cleanup: added "`make analyse`" to run "`splint`" and "`flawfinder`" on all source files
|
||||
* cleanup: corrected detection of boolean capability
|
||||
* cleanup: word wrapping of "`--help`" output is now multi-byte locale aware
|
||||
* cleanup: adjusted "`indent`" rules to line length of 120 and reformatted code
|
||||
|
||||
1.7.18 - 28 July 2023
|
||||
|
||||
* fix: language file installation had been broken by the configuration script rewrite
|
||||
|
||||
1.7.17 - 27 July 2023
|
||||
|
||||
* feature: new "`--sync`" option to flush cache to disk after every write (related to [GH#6](https://github.com/a-j-wood/pv/issues/6), to improve accuracy when writing to slow disks)
|
||||
* feature: new "`--direct-io`" option to bypass cache - implements [GH#29 "Option to enable *O_DIRECT*"](https://github.com/a-j-wood/pv/issues/29) - requested by Romain Kang, Jacek Wielemborek
|
||||
* fix: correct byte prefix size to 2 spaces in rate display, so progress display size remains constant at low transfer rates
|
||||
* cleanup: rewrote `configure.in` as per suggestions in newer "`autoconf`" manuals
|
||||
* cleanup: replaced `header.in` with one generated by "`autoheader`", moving custom logic to a separate header file "`config-aux.h`"
|
||||
* cleanup: added copyright notice to all source files as per GNU standards
|
||||
* cleanup: changed "`--version`" output to conform to GNU standards
|
||||
* cleanup: replaced backticks with `$()` in all shell scripts that did not come from elsewhere, as backticks are deprecated and harder to read
|
||||
* cleanup: improved the output formatting of "`make test`"
|
||||
* cleanup: extended the "`make test`" mechanism to allow certain tests to be skipped on platforms that cannot support them
|
||||
* cleanup: skip the "pipe" test (for *SIGPIPE*) if GNU "`head`" is not available, so that "`make test`" on stock OpenBSD 7.3 works
|
||||
* cleanup: added a lot more tests to "`make test`"
|
||||
* cleanup: replace all calls to `sprintf()` and `snprintf()` with a new wrapper function `pv_snprintf()` to improve security and compatibility
|
||||
* cleanup: replace all calls to `strcat()` with a wrapper `pv_strlcat()` to improve security and compatibility
|
||||
* cleanup: replace all `write()` calls to the terminal with a wrapper `pv_write_retry()` for consistency
|
||||
* cleanup: tidy up and fix compilation warning in "`--watchfd`" code
|
||||
* cleanup: rewrote all local shell scripts to pass analysis by [ShellCheck](https://www.shellcheck.net)
|
||||
|
||||
1.7.0 - 17 July 2023
|
||||
|
||||
* dropped: support for Red Hat Enterprise Linux and its derivatives has been dropped; removed the RPM spec file, and will no longer build binaries
|
||||
* feature: the "`--size`" option now accepts "`@filename`" to use the size of another file (pull request [#57](https://github.com/a-j-wood/pv/pull/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* feature: the "`--watchfd`" option is now available on OS X (pull request [#60](https://github.com/a-j-wood/pv/pull/60) supplied by [christoph-zededa](https://github.com/christoph-zededa))
|
||||
* feature: new "`--bits`" option to show bit count instead of byte count (adapted from pull request [#63](https://github.com/a-j-wood/pv/pull/63) supplied by [Nick Black](https://nick-black.com))
|
||||
* feature: new "`--average-rate-window`" option, to set the window over which the average rate is calculated, also used for ETA (modified from pull request [#65](https://github.com/a-j-wood/pv/pull/65) supplied by [lemonsqueeze](https://github.com/lemonsqueeze))
|
||||
* feature: the "`--watchfd`" option will now show relative filenames, if they are under the current directory (pull request [#66](https://github.com/a-j-wood/pv/pull/66) supplied by [ikasty](https://github.com/ikasty))
|
||||
* fix: correction to `pv_in_foreground()` to behave as its comment block says it should, when not on a terminal - corrects [GH#19 "No output in Arch Linux initcpio after 1.6.6"](https://github.com/a-j-wood/pv/issues/19), [GH#31 "No output written from inside zsh <() construct"](https://github.com/a-j-wood/pv/issues/31), [GH#55 "pv Stopped Working in the Background"](https://github.com/a-j-wood/pv/issues/55) (pull request [#64](https://github.com/a-j-wood/pv/pull/64) supplied by [Michael Weiß](https://github.com/quitschbo))
|
||||
* fix: workaround for OS X 11 behaviour in configure script regarding stat64 at compile time (pull request [#57](https://github.com/a-j-wood/pv/pull/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* fix: workaround for macOS equivalence of stat to stat64 - patches from [Filippo Valsorda](https://github.com/FiloSottile) and [Demitri Muna](https://github.com/demitri), correcting [GH#33 "Fix compilation problems due to `stat64()` on Apple Silicon"](https://github.com/a-j-wood/pv/issues/33)
|
||||
* fix: add burst rate limit to transfer, so rate limits are not broken by bursty traffic (pull request [#62](https://github.com/a-j-wood/pv/pull/62) supplied by [Volodymyr Bychkovyak](https://github.com/vbychkoviak))
|
||||
* fix: corrected "`--force`" option so it will still output progress when not in the same process group as the owner of the terminal - corrects [GH#23 "No output with "`-f`" when run in background after 1.6.6"](https://github.com/a-j-wood/pv/issues/23) and helps to correct [GH#31 "No output written from inside zsh <() construct"](https://github.com/a-j-wood/pv/issues/31)
|
||||
* fix: corrected elapsed time display to show as D:HH:MM:SS after 1 day, like the ETA does - corrects [GH#16 "Show days in same format in ETA as in elapsed time"](https://github.com/a-j-wood/pv/issues/16)
|
||||
* fix: corrected bug where percentages went down after 100% when in "`--numeric`" mode with a "`--size`" that was too small - corrects [GH#26 "Correct "`-n`" behaviour when going past 100% of "`-s`" size"](https://github.com/a-j-wood/pv/issues/26)
|
||||
* i18n: recoded Polish translation file to UTF-8
|
||||
* i18n: removed inaccurate fuzzy translation matches
|
||||
* docs: moved all open issues into GitHub and updated the TODO list
|
||||
* docs: renamed README to README.md and altered it to Markdown format
|
||||
* docs: moved contributors from the README to docs/ACKNOWLEDGEMENTS.md
|
||||
* docs: moved TODO to TODO.md and altered it to Markdown format
|
||||
* docs: moved NEWS to NEWS.md, converted it to UTF-8, and altered it to Markdown format
|
||||
|
||||
1.6.20 - 12 September 2021
|
||||
|
||||
* fix: add missing `stddef.h` include to `number.c` (Sam James)
|
||||
|
||||
1.6.19 - 5 September 2021
|
||||
|
||||
* fix: starting pv in the background no longer immediately stops unless the transfer is to/from the terminal (Andriy Gapon, Jonathan Elchison)
|
||||
* fix: using "`-B`", "`-A`", or "`-T`" now switches on "`-C`" implicitly (Johannes Gerer, André Stapf)
|
||||
* fix: AIX build fixes (Peter Korsgaard)
|
||||
* i18n: updated German "`--help`" translations (Richard Fonfara)
|
||||
* i18n: switched to UTF-8 encoding, added missing translations (de,fr,pt)
|
||||
* docs: new "common switches" manual section (Jacek Wielemborek)
|
||||
* docs: use placeholder instead of `/dev/sda` in the manual (Pranav Peshwe)
|
||||
* docs: mention MacOS pipes and "`-B 1024`" in the manual (Jan Venekamp)
|
||||
* docs: correct shell in `autoconf/scripts/index.sh` (Juan Picca)
|
||||
* cleanup: various compiler warnings cleaned up
|
||||
|
||||
Full changelog is below:
|
||||
* (r181) added common switches section to manual (Jacek Wielemborek)
|
||||
* (r184) use placeholder instead of /dev/sda in the manual (Pranav Peshwe)
|
||||
* (r185) replace ash with sh in autoconf/scripts/index.sh (Juan Picca)
|
||||
* (r185) added note to manual about "`-B 1024`" in MacOS pipes (Jan Venekamp)
|
||||
* (r185) fix AIX config check when the CWD contains "yes" (Peter Korsgaard)
|
||||
* (r189) (#1556) updated German "`--help`" translations (Richard Fonfara)
|
||||
* (r189) updated missing German translations and changed to UTF-8 encoding
|
||||
* (r191) updated missing French translations and changed to UTF-8 encoding
|
||||
* (r193) updated missing Portuguese translations, changed to UTF-8 encoding
|
||||
* (r196) (#1563) using "`-B`", "`-A`", or "`-T`" now switches on "`-C`" implicitly (Johannes Gerer, André Stapf)
|
||||
* (r199) fixed numerous compiler warnings in newer GCC versions
|
||||
* (r200,205) fixed bug where "`pv /dev/zero >/dev/null &`" stopped immediately (Jonathan Elchison, Andriy Gapon)
|
||||
* (r203,205) marked unused arguments with GCC unused attribute, started using boolean data type for flags, corrected more compiler warnings
|
||||
|
||||
1.6.6 - 30 June 2017
|
||||
|
||||
* (r161) use `%llu` instead of `%Lu` for better compatibility (Eric A. Borisch)
|
||||
* (r162) (#1532) fix target buffer size ("`-B`") being ignored (AndCycle, Ilya Basin, Antoine Beaupré)
|
||||
* (r164) cap read/write sizes, and check elapsed time during read/write cycles, to avoid display hangs with large buffers or slow media; also remove `select()` call from repeated_write function as it slows the transfer down and the wrapping `alarm()` means it is unnecessary
|
||||
* (r169) (#1477) use alternate form for transfer counter, such that 13GB is shown as 13.0GB so it's the same width as 13.1GB (André Stapf)
|
||||
* (r171) cleanup: units corrections in man page, of the form kb -> KiB
|
||||
* (r175) report error in "`-d`" if process fd directory is unreadable, or if process disappears before we start the main loop (Jacek Wielemborek)
|
||||
|
||||
1.6.0 - 15 March 2015
|
||||
|
||||
* fix lstat64 support when unavailable - separate patches supplied by Ganael Laplanche and Peter Korsgaard
|
||||
* (#1506) new option "`-D`" / "`--delay-start`" to only show bar after N seconds (Damon Harper)
|
||||
* new option "`--fineta`" / "`-I`" to show ETA as time of day rather than time remaining - patch supplied by Erkki Seppälä (r147)
|
||||
* (#1509) change ETA ("`--eta`" / "`-e`") so that days are given if the hours remaining are 24 or more (Jacek Wielemborek)
|
||||
* (#1499) repeat read and write attempts on partial buffer fill/empty to work around post-signal transfer rate drop reported by Ralf Ramsauer
|
||||
* (#1507) do not try to calculate total size in line mode, due to bug reported by Jacek Wielemborek and Michiel Van Herwegen
|
||||
* cleanup: removed defunct RATS comments and unnecessary copyright notices
|
||||
* clean up displayed lines when using "`--watchfd PID`", when PID exits
|
||||
* output errors on a new line to avoid overwriting transfer bar
|
||||
|
||||
1.5.7 - 26 August 2014
|
||||
|
||||
* show KiB instead of incorrect kiB (Debian bug #706175)
|
||||
* (#1284) do not gzip man page, for non-Linux OSes (Bob Friesenhahn)
|
||||
* work around "awk" bug in `tests/016-numeric-timer` in decimal "," locales
|
||||
* fix "`make rpm`" and "`make srpm`", extend "`make release`" to sign releases
|
||||
|
||||
1.5.3 - 4 May 2014
|
||||
|
||||
* remove *SPLICE_F_NONBLOCK* to fix problem with slow `splice()` (Jan Seda)
|
||||
|
||||
1.5.2 - 10 February 2014
|
||||
|
||||
* allow "`--watchfd`" to look at block devices
|
||||
* let "`--watchfd PID:FD`" work with "`--size N`"
|
||||
* moved contributors out of the manual as the list was too long (NB everyone is still listed in the README and always will be)
|
||||
|
||||
1.5.1 - 23 January 2014
|
||||
|
||||
* new option "`--watchfd`" - suggested by Jacek Wielemborek and "fdwatch"
|
||||
* use non-block flag with `splice()`
|
||||
* new display option "`--buffer-percent`", suggested by Kim Krecht
|
||||
* new display option "`--last-written`", suggested by Kim Krecht
|
||||
* new transfer option "`--no-splice`"
|
||||
* fix for minor bug which dropped display elements after one empty one
|
||||
* fix for single fd leak on exit (Cristian Ciupitu)
|
||||
|
||||
1.4.12 - 5 August 2013
|
||||
|
||||
* new option "`--null`" - patch supplied by Zing Shishak
|
||||
* AIX build fix (add "`-lc128`") - with help from Pawel Piatek
|
||||
* AIX "`-c`" fixes - with help from Pawel Piatek
|
||||
* SCO build fix (`po2table.sh`) - reported by Wouter Pronk
|
||||
* test scripts fix for older distributions - patch from Bryan Dongray
|
||||
* fix for `splice()` not using stdin - patch from Zev Weiss
|
||||
|
||||
1.4.6 - 22 January 2013
|
||||
|
||||
* added patch from Pawel Piatek to omit *O_NOFOLLOW* in AIX
|
||||
|
||||
1.4.5 - 10 January 2013
|
||||
|
||||
* updated manual page to show known problem with "`-R`" on Cygwin
|
||||
|
||||
1.4.4 - 11 December 2012
|
||||
|
||||
* added debugging, see "`pv -h`" when `configure` is run with "`--enable-debugging`"
|
||||
* rewrote cursor positioning code used when IPC is unavailable (Cygwin)
|
||||
* fixed cursor positioning cursor read answerback problem (Cygwin/Solaris)
|
||||
* fixed bug causing crash when progress displayed with too-small terminal
|
||||
|
||||
1.4.0 - 6 December 2012
|
||||
|
||||
* new option "`--skip-errors`" commissioned by Jim Salter
|
||||
* if stdout is a block device, and we don't know the total size, use the size of that block device as the total (Peter Samuelson)
|
||||
* new option "`--stop-at-size`" to stop after "`--size`" bytes
|
||||
* report correct filename on read errors
|
||||
* fix use-after-free bug in remote PID cleanup code
|
||||
* refactored large chunks of code to make it more readable and to replace most static variables with a state structure
|
||||
|
||||
1.3.9 - 5 November 2012
|
||||
|
||||
* allow "`--format`" parameters to be sent with "`--remote`"
|
||||
* configure option "`--disable-ipc`"
|
||||
* added tests for "`--numeric`" with "`--timer`" and "`--bytes`"
|
||||
* added tests for "`--remote`"
|
||||
|
||||
1.3.8 - 29 October 2012
|
||||
|
||||
* new "`--pidfile`" option to save process ID to a file
|
||||
* integrated patch for "`--numeric`" with "`--timer`" and "`--bytes`" (Sami Liedes)
|
||||
* removed signalling from "`--remote`" to prevent accidental process kills
|
||||
* new "`--format`" option (originally Vladimir Pal / Vladimir Ermakov)
|
||||
|
||||
1.3.4 - 27 June 2012
|
||||
|
||||
* new "`--disable-splice`" configure script option
|
||||
* fixed line mode size count with multiple files (Moritz Barsnick)
|
||||
* fixes for AIX core dumps (Pawel Piatek)
|
||||
|
||||
1.3.1 - 9 June 2012
|
||||
|
||||
* do not use `splice()` if the write buffer is not empty (Thomas Rachel)
|
||||
* added test 15 (pipe transfers), and new test script
|
||||
|
||||
1.3.0 - 5 June 2012
|
||||
|
||||
* added Tiger build patch from Olle Jonsson
|
||||
* fix 1024-boundary display garble (Debian bug #586763)
|
||||
* use `splice`(2) where available (Debian bug #601683)
|
||||
* added known bugs section of the manual page
|
||||
* fixed average rate test, 12 (Andrew Macheret)
|
||||
* use IEEE1541 units (Thomas Rachel)
|
||||
* bug with rate limit under 10 fixed (Henry Precheur)
|
||||
* speed up PV line mode (patch: Guillaume Marcais)
|
||||
* remove `LD=ld` from `vars.mk` to fix cross-compilation (paintitgray/PV#1291)
|
||||
|
||||
1.2.0 - 14 December 2010
|
||||
|
||||
* integrated improved SI prefixes and "`--average-rate`" (Henry Gebhardt)
|
||||
* return nonzero if exiting due to *SIGTERM* (Martin Baum)
|
||||
* patch from Phil Rutschman to restore terminal properly on exit
|
||||
* fix i18n especially for "`--help`" (Sebastian Kayser)
|
||||
* refactored `pv_display`
|
||||
* we now have a coherent, documented, exit status
|
||||
* modified pipe test and new cksum test from Sebastian Kayser
|
||||
* default *CFLAGS* to just "`-O`" for non-GCC (Kjetil Torgrim Homme)
|
||||
* LFS compile fix for OS X 10.4 (Alexandre de Verteuil)
|
||||
* remove *DESTDIR* `/` suffix (Sam Nelson, Daniel Pape)
|
||||
* fixed potential NULL deref in transfer (Elias Pipping / LLVM/Clang)
|
||||
|
||||
1.1.4 - 6 March 2008
|
||||
|
||||
* patch from Elias Pipping correcting compilation failure on Darwin 9
|
||||
* patch from Patrick Collison correcting similar problems on OS X
|
||||
* trap *SIGINT* / *SIGHUP* / *SIGTERM* so we clean up IPCs on exit (Laszlo Ersek)
|
||||
* abort if numeric option, eg "`-L`", has non-numeric value (Boris Lohner)
|
||||
|
||||
1.1.0 - 30 August 2007
|
||||
|
||||
* new option "`--remote`" ("`-R`") to control an already-running process
|
||||
* new option "`--line-mode`" ("`-l`") to count lines instead of bytes
|
||||
* fix for "`-L`" to be less resource intensive
|
||||
* fix for input/output equivalence check on Mac OS X
|
||||
* fix for size calculation in pipelines on Mac OS X
|
||||
* fixed "`make uninstall`"
|
||||
* removed "`/debian`" directory at request of new Debian maintainer
|
||||
|
||||
1.0.1 - 4 August 2007
|
||||
|
||||
* licensing change from Artistic to Artistic 2.0
|
||||
* removed the "`-l`" / "`--license`" option
|
||||
|
||||
1.0.0 - 2 August 2007
|
||||
|
||||
* act more like "`cat`" - just skip unreadable files, don't abort
|
||||
* removed text version of manual page, and obsolete Info file generation
|
||||
* code cleanup and separation of PV internals from CLI front-end
|
||||
|
||||
0.9.9 - 5 February 2007
|
||||
|
||||
* new option "`--buffer-size`" ("`-B`") suggested by Mark Tomich
|
||||
* build fix: HP/UX largefile compile fix from Timo Savinen
|
||||
* maintain better buffer filling during transfers
|
||||
* workaround: "`pv /dev/zero | dd bs=1M count=1k`" bug (reported by Gert Menke)
|
||||
* dropped support for the Texinfo manual
|
||||
|
||||
0.9.6 - 27 February 2006
|
||||
|
||||
* bugfix: `key_t` incompatibility with Cygwin
|
||||
* bugfix: interval ("`-i`") parameter parses numbers after decimal point
|
||||
* build fix: use static NLS if `msgfmt` is unavailable
|
||||
* on the final update, blank out the now-zero ETA
|
||||
|
||||
0.9.2 - 1 September 2005
|
||||
|
||||
* Daniel Roethlisberger patch: use lockfiles if terminal locking fails
|
||||
|
||||
0.9.1 - 16 June 2005
|
||||
|
||||
* minor RPM spec file fix for Fedora Core 4
|
||||
|
||||
0.9.0 - 15 November 2004
|
||||
|
||||
* minor NLS bugfix
|
||||
|
||||
0.8.9 - 6 November 2004
|
||||
|
||||
* decimal values now accepted for rate and size, eg "`-L 1.23M`"
|
||||
* code cleanup
|
||||
* developers: "`make help`" now lists Makefile targets
|
||||
|
||||
0.8.6 - 29 June 2004
|
||||
|
||||
* use `uu_lock()` for terminal locking on FreeBSD
|
||||
|
||||
0.8.5 - 2 May 2004
|
||||
|
||||
* cursor positioning ("`-c`") reliability improved on systems with IPC
|
||||
* minor fix: made test 005 more reliable
|
||||
* new option "`--height`" ("`-H`")
|
||||
|
||||
0.8.2 - 24 April 2004
|
||||
|
||||
* allow k,m,g,t suffixes on numbers
|
||||
* added "`srpm`" and "`release`" Makefile targets
|
||||
|
||||
0.8.1 - 19 April 2004
|
||||
|
||||
* bugfix in cursor positioning ("`-c`")
|
||||
|
||||
0.8.0 - 12 February 2004
|
||||
|
||||
* replaced GNU getopt with my library code
|
||||
* replaced GNU gettext with my very minimal replacement
|
||||
* use *DESTDIR* instead of *RPM_BUILD_ROOT* for optional installation prefix
|
||||
* looked for flaws using RATS, cleaned up code
|
||||
|
||||
0.7.0 - 8 February 2004
|
||||
|
||||
* display buffer management fixes (thanks Cédric Delfosse)
|
||||
* replaced "`--enable-debug`" with "`--enable-debugging`" and "`--enable-profiling`"
|
||||
|
||||
0.6.4 - 14 January 2004
|
||||
|
||||
* fixed minor bug in RPM installation
|
||||
* bugfix in "`make index`" (only of interest to developers)
|
||||
|
||||
0.6.3 - 22 December 2003
|
||||
|
||||
* fixed transient bug that reported "resource unavailable" occasionally
|
||||
|
||||
0.6.2 - 6 August 2003
|
||||
|
||||
* block devices now have their size read correctly, so "`pv /dev/hda1`" works
|
||||
* minor code cleanups (mainly removal of CVS "Id" tags)
|
||||
|
||||
0.6.0 - 3 August 2003
|
||||
|
||||
* doing *^Z* then "`bg`" then "`fg`" now continues displaying
|
||||
|
||||
0.5.9 - 23 July 2003
|
||||
|
||||
* fix for test 007 when not in C locale
|
||||
* fix for build process to use *CPPFLAGS*
|
||||
* fix for build process to use correct i18n libraries
|
||||
* fix for build process - more portable sed in dependency generator
|
||||
* fix for install process - remember to `mkinstalldirs` before installing
|
||||
* fixes for building on Mac OS X
|
||||
|
||||
0.5.3 - 4 May 2003
|
||||
|
||||
* added Polish translation thanks to Bartosz Feński <fenio@o2.pl> <http://skawina.eu.org/> and Krystian Zubel
|
||||
* moved `doc/debian` to `./debian` at insistence of common sense
|
||||
* minor Solaris 8 compatibility fixes
|
||||
* seems to compile and test OK on Mac OS X
|
||||
|
||||
0.5.0 - 15 April 2003
|
||||
|
||||
* added French translation thanks to Stéphane Lacasse <stephane@gorfou.ca>
|
||||
* added German translation thanks to Marcos Kreinacke <public@kreinacke.com>
|
||||
* switched LGPL reference from "Library" to "Lesser"
|
||||
|
||||
0.4.9 - 18 February 2003
|
||||
|
||||
* support for >2GB files added where available (Debian bug #180986)
|
||||
* added `doc/debian` dir (from Cédric Delfosse)
|
||||
* added "`make rpm`" and "`make deb`" targets to build RPM and Debian packages
|
||||
* added a "`make pv-static`" rule to build a statically linked version
|
||||
|
||||
0.4.5 - 13 December 2002
|
||||
|
||||
* added Portuguese (Brazilian) translation thanks to Eduardo Aguiar
|
||||
|
||||
0.4.4 - 7 December 2002
|
||||
|
||||
* pause/resume support - don't count time while stopped
|
||||
* stop output when resumed in the background
|
||||
* terminal size change support
|
||||
* bugfix: "`<=>`" indicator no longer sticks at right hand edge
|
||||
|
||||
0.4.0 - 27 November 2002
|
||||
|
||||
* allow decimal interval values, eg 0.1, 0.5, etc
|
||||
* some simple tests added ("`make check`")
|
||||
* smoother throughput limiting ("`--rate-limit`"), now done in 0.1sec chunks
|
||||
* bounds-check interval values ("`-i`") - max update interval now 10 minutes
|
||||
* more reliable non-blocking output to keep display updated
|
||||
* no longer rely on `atoll()`
|
||||
* don't output final blank line if "`--numeric`"
|
||||
* use `fcntl()` instead of `flock()` for Solaris compatibility
|
||||
|
||||
0.3.0 - 25 November 2002
|
||||
|
||||
* handle broken output pipe gracefully
|
||||
* continue updating display even when output pipe is blocking
|
||||
|
||||
0.2.6 - 21 October 2002
|
||||
|
||||
* we now ignore *EINTR* on `select()`
|
||||
* variable-size buffer (still need to add code to change size)
|
||||
* added (tentative) support for internationalisation
|
||||
* removed superfluous "`--no-progress`", etc options
|
||||
* optimised transfer by using bigger buffers, based on `st_blksize`
|
||||
* added "`--wait`" option to wait until transfer begins before showing progress
|
||||
* added "`--rate-limit`" option to limit rate to a maximum throughput
|
||||
* added "`--quiet`" option (no output at all) to be used with "`--rate-limit`"
|
||||
|
||||
0.2.5 - 23 July 2002
|
||||
|
||||
* added *[FILE]...* arguments, like "`cat`"
|
||||
* function separation in code
|
||||
* some bug fixes related to numeric overflow
|
||||
|
||||
0.2.3 - 19 July 2002
|
||||
|
||||
* Texinfo manual written, man page updated
|
||||
* byte counter added
|
||||
|
||||
0.2.0 - 18 July 2002
|
||||
|
||||
* ETA counter added
|
||||
* screen width estimation added
|
||||
* progress bar added
|
||||
|
||||
0.1.0 - 17 July 2002
|
||||
|
||||
* main loop created
|
||||
* rate counter added
|
||||
* elapsed time counter added
|
||||
* percentage calculation added
|
||||
|
||||
0.0.1 - 16 July 2002
|
||||
|
||||
* package created
|
||||
* first draft of man page written
|
||||
@@ -1 +0,0 @@
|
||||
pv
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
Things still to do. (GH#n) indicates the Github issue tracker number.
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
* ([GH#5](https://github.com/a-j-wood/pv/issues/5)) Transfer IPC leadership on exit of leader
|
||||
* ([GH#13](https://github.com/a-j-wood/pv/issues/13)) Use `clock_gettime()` in ETA calculation to cope with machine suspend/resume (Mateju Miroslav)
|
||||
* ([GH#20](https://github.com/a-j-wood/pv/issues/20)) Terminal state is not restored correctly in all cases (VA)
|
||||
* ([GH#24](https://github.com/a-j-wood/pv/issues/24)) Race condition with multiple "`pv -c`" leaves terminal state inconsistent (Lars Ellenberg, Viktor Ashirov)
|
||||
* ([GH#34](https://github.com/a-j-wood/pv/issues/34)) Continue timer even if input or output is blocking (Martin Probst - Jun 2017)
|
||||
|
||||
Feature requests
|
||||
----------------
|
||||
|
||||
* ([GH#3](https://github.com/a-j-wood/pv/issues/3)) Option ("`-x`"?) to use xterm title line for status (Joachim Haga)
|
||||
* ([GH#4](https://github.com/a-j-wood/pv/issues/4)) Option for process title (Martin Sarsale) as "`pv - name:FooProcess -xyz - transferred: 1.3GB - 500KB/s - running: 10:15:30s`"
|
||||
* ([GH#6](https://github.com/a-j-wood/pv/issues/6)) Look at effect of *O_SYNC* or `fsync` on performance; update counters during buffer flush
|
||||
* ([GH#9](https://github.com/a-j-wood/pv/issues/9)) Option to switch rate to per minute if really slow
|
||||
* ([GH#10](https://github.com/a-j-wood/pv/issues/10)) Add watchfd tests
|
||||
* ([GH#11](https://github.com/a-j-wood/pv/issues/11)) Option "`--progress-from FILE`", read last number and use it as bytes read (Jacek Wielemborek)
|
||||
* ([GH#12](https://github.com/a-j-wood/pv/issues/12)) Allow multiple "`-d`" options (Linus Heckemann for multiple PID:FD; Jacek Wielemborek)
|
||||
* ([GH#15](https://github.com/a-j-wood/pv/issues/15)) Use Unicode for more granular progress bar (Alexander Petrossian)
|
||||
* ([GH#17](https://github.com/a-j-wood/pv/issues/17)) Allow "`-r`" with "`-l`" and "`-n`" to output lines/sec (Roland Kletzing)
|
||||
* ([GH#22](https://github.com/a-j-wood/pv/issues/22)) Options to skip input and seek on output (Jason A. Pfeil, Feb 2022)
|
||||
* ([GH#25](https://github.com/a-j-wood/pv/issues/25)) Normalise progress to 100% on overrun (Andrej Gantvorg)
|
||||
* ([GH#35](https://github.com/a-j-wood/pv/issues/35)) Allow decimal values for "`-s`", "`-L`", "`-B`" (Thomas Watson - Aug 2020)
|
||||
* ([GH#36](https://github.com/a-j-wood/pv/issues/36)) Ignore *SIGWINCH* (window size change) if "`-w`" / "`-H`" provided
|
||||
* ([GH#37](https://github.com/a-j-wood/pv/issues/37)) Allow "`-E`" to take a block size argument so errors cause a skip to the next block (Anthony DeRobertis - Oct 2016)
|
||||
* ([GH#38](https://github.com/a-j-wood/pv/issues/38)) Reset ETA on *SIGUSR1* (Jacek Wielemborek - Jan 2019)
|
||||
* ([GH#39](https://github.com/a-j-wood/pv/issues/39)) Use `posix_fadvise()` like `cat`(1) does (Jacek Wielemborek - Oct 2015)
|
||||
* ([GH#40](https://github.com/a-j-wood/pv/issues/40)) Permit "`-c`" with "`-d PID:FD`", reject "`-N`" with "`-d PID`" (Norman Rasmussen - Nov 2020)
|
||||
* ([GH#41](https://github.com/a-j-wood/pv/issues/41)) Improve how backwards-moving reads are shown in "`--watchfd`" (Ryan Cooley - Dec 2017)
|
||||
* ([GH#42](https://github.com/a-j-wood/pv/issues/42)) Option to discard stdin so nothing is written to stdout (André Stapf - Apr 2017)
|
||||
* ([GH#43](https://github.com/a-j-wood/pv/issues/43)) Differentiate between "`--eta`" and "`--fineta`" in display (André Stapf - Apr 2017)
|
||||
* ([GH#45](https://github.com/a-j-wood/pv/issues/45)) Option "`--sparse`" (with block size option) to write sparse output (Andriy Galetski - Apr 2019)
|
||||
* ([GH#46](https://github.com/a-j-wood/pv/issues/46)) Option to show speed gauge (% max speed) if progress not known (Ryan Cooley - Jun 2019)
|
||||
* ([GH#47](https://github.com/a-j-wood/pv/issues/47)) Analyse splice and buffer usage to improve performance
|
||||
* ([GH#48](https://github.com/a-j-wood/pv/issues/48)) Option to show multiple files with individual sizes and a cumulative total (Zach Riggle - Jul 2021)
|
||||
* ([GH#49](https://github.com/a-j-wood/pv/issues/49)) Option to provide stats for avg/min/max/stddev throughput (Venky.N.Iyer)
|
||||
* ([GH#50](https://github.com/a-j-wood/pv/issues/50)) Allow pv to report on a whole pipeline at once (Will Entriken - Feb 2011)
|
||||
* ([GH#54](https://github.com/a-j-wood/pv/issues/54)) Run command every n percent ([haarp](https://github.com/haarp))
|
||||
* ([GH#56](https://github.com/a-j-wood/pv/issues/56)) Support for backgrounding pv, and allowing it to be monitored separately ([jimbobmcgee](https://github.com/jimbobmcgee))
|
||||
* ([GH#67](https://github.com/a-j-wood/pv/issues/67)) Wrap another process to monitor its stdin & stdout ([Alex Mason](https://github.com/axman6))
|
||||
|
||||
Any assistance would be appreciated.
|
||||
@@ -1 +0,0 @@
|
||||
1.7.24
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
Begin3
|
||||
Title: @PACKAGE@
|
||||
Version: @VERSION@
|
||||
Entered-date: 30JUL23
|
||||
Description: A tool for monitoring the progress of data through a
|
||||
pipeline. It can be inserted into any normal pipeline
|
||||
between two processes to give a visual indication of how
|
||||
quickly data is passing through, how long it has taken, how
|
||||
near to completion it is, and an estimate of how long it
|
||||
will be until completion.
|
||||
Keywords: progress bar, console, pipe, transfer rate
|
||||
Author: Andrew Wood <andrew.wood@ivarch.com>
|
||||
Maintained-by: Andrew Wood <andrew.wood@ivarch.com>
|
||||
Primary-site: http://www.ivarch.com/programs/@PACKAGE@.shtml
|
||||
Alternate-site:
|
||||
Original-site:
|
||||
Platforms:
|
||||
Copying-policy: Artistic 2.0
|
||||
End
|
||||
@@ -1,681 +0,0 @@
|
||||
.TH @UCPACKAGE@ 1 "July 2023" Linux "User Manuals"
|
||||
.SH NAME
|
||||
@PACKAGE@ \- monitor the progress of data through a pipe
|
||||
.SH SYNOPSIS
|
||||
.B @PACKAGE@
|
||||
[\fIOPTION\fR]
|
||||
[\fIFILE\fR]...
|
||||
.br
|
||||
.B @PACKAGE@
|
||||
[\fI\-h\fR|\fI\-V\fR]
|
||||
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B @PACKAGE@
|
||||
shows the progress of data through a pipeline by giving information such as
|
||||
time elapsed, percentage completed (with progress bar), current throughput
|
||||
rate, total data transferred, and ETA.
|
||||
|
||||
To use it, insert it in a pipeline between two processes, with the
|
||||
appropriate options. Its standard input will be passed through to its
|
||||
standard output and progress will be shown on standard error.
|
||||
|
||||
.B @PACKAGE@
|
||||
will copy each supplied
|
||||
.B FILE
|
||||
in turn to standard output
|
||||
.BR "" "(" -
|
||||
means standard input), or if no
|
||||
.BR FILE s
|
||||
are specified just standard input is copied. This is the same behaviour
|
||||
as
|
||||
.BR cat (1).
|
||||
|
||||
A simple example to watch how quickly a file is transferred using
|
||||
.BR nc (1):
|
||||
|
||||
.RS
|
||||
.B @PACKAGE@ file | nc -w 1 somewhere.com 3000
|
||||
.RE
|
||||
|
||||
A similar example, transferring a file from another process and passing the
|
||||
expected size to
|
||||
.BR @PACKAGE@ :
|
||||
|
||||
.RS
|
||||
.B cat file | @PACKAGE@ -s 12345 | nc -w 1 somewhere.com 3000
|
||||
.RE
|
||||
|
||||
A more complicated example using numeric output to feed into the
|
||||
.BR dialog (1)
|
||||
program for a full-screen progress display:
|
||||
|
||||
.RS
|
||||
.B (tar cf - . \e
|
||||
.br
|
||||
.B " | @PACKAGE@ -n -s $(du -sb . | awk '{print $1}') \e"
|
||||
.br
|
||||
.B " | gzip -9 > out.tgz) 2>&1 \e"
|
||||
.br
|
||||
.B | dialog --gauge 'Progress' 7 70
|
||||
.RE
|
||||
|
||||
Taking an image of a disk, skipping errors:
|
||||
|
||||
.RS
|
||||
.B @PACKAGE@ -EE /dev/your/disk/device > disk-image.img
|
||||
.RE
|
||||
|
||||
Writing an image back to a disk:
|
||||
|
||||
.RS
|
||||
.B @PACKAGE@ disk-image.img > /dev/your/disk/device
|
||||
.RE
|
||||
|
||||
Zeroing a disk:
|
||||
|
||||
.RS
|
||||
.B @PACKAGE@ < /dev/zero > /dev/your/disk/device
|
||||
.RE
|
||||
|
||||
Note that if the input size cannot be calculated, and the output is a block
|
||||
device, then the size of the block device will be used and
|
||||
.B @PACKAGE@
|
||||
will automatically stop at that size as if
|
||||
.B \-S
|
||||
had been given.
|
||||
|
||||
(Linux only): Watching file descriptor 3 opened by another process 1234:
|
||||
|
||||
.RS
|
||||
.B @PACKAGE@ -d 1234:3
|
||||
.RE
|
||||
|
||||
(Linux only): Watching all file descriptors used by process 1234:
|
||||
|
||||
.RS
|
||||
.B @PACKAGE@ -d 1234
|
||||
.RE
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
.B @PACKAGE@
|
||||
takes many options, which are divided into display switches, output
|
||||
modifiers, and general options.
|
||||
|
||||
|
||||
.SH DISPLAY SWITCHES
|
||||
If no display switches are specified,
|
||||
.B @PACKAGE@
|
||||
behaves as if
|
||||
.BR \-p ", " \-t ", " \-e ", " \-r ", and " \-b
|
||||
had been given (i.e. everything except average rate is switched on).
|
||||
Otherwise, only those display types that are explicitly switched on will be
|
||||
shown.
|
||||
.TP
|
||||
.B \-p, \-\-progress
|
||||
Turn the progress bar on. If standard input is not a file and no
|
||||
size was given (with the
|
||||
.B \-s
|
||||
modifier), the progress bar cannot indicate how close to completion the
|
||||
transfer is, so it will just move left and right to indicate that data is
|
||||
moving.
|
||||
.TP
|
||||
.B \-t, \-\-timer
|
||||
Turn the timer on. This will display the total elapsed time that
|
||||
.B @PACKAGE@
|
||||
has been running for.
|
||||
.TP
|
||||
.B \-e, \-\-eta
|
||||
Turn the ETA timer on. This will attempt to guess, based on current
|
||||
transfer rates and the total data size, how long it will be before
|
||||
completion. This option will have no effect if the total data size cannot
|
||||
be determined.
|
||||
.TP
|
||||
.B \-I, \-\-fineta
|
||||
Turn the ETA timer on, but display the estimated local time of arrival
|
||||
instead of time left. When the estimated time is more than 6 hours in the
|
||||
future, the date is shown as well.
|
||||
.TP
|
||||
.B \-r, \-\-rate
|
||||
Turn the rate counter on. This will display the current rate of data
|
||||
transfer.
|
||||
.TP
|
||||
.B \-a, \-\-average\-rate
|
||||
Turn the average rate counter on. This will display the current average
|
||||
rate of data transfer (default: last 30s, see --average-rate-window).
|
||||
.TP
|
||||
.B \-b, \-\-bytes
|
||||
Turn the total byte counter on. This will display the total amount of
|
||||
data transferred so far.
|
||||
.TP
|
||||
.B \-8, \-\-bits
|
||||
Display the total bits instead of the total bytes. The output suffix will
|
||||
be "b" instead of "B".
|
||||
.TP
|
||||
.B \-T, \-\-buffer\-percent
|
||||
Turn on the transfer buffer percentage display. This will show the
|
||||
percentage of the transfer buffer in use - but see the caveat under
|
||||
.B %T
|
||||
in the
|
||||
.B FORMATTING
|
||||
section below. Implies
|
||||
.BR \-C .
|
||||
.TP
|
||||
.B \-A, \-\-last\-written NUM
|
||||
Show the last
|
||||
.B NUM
|
||||
bytes written - but see the caveat under
|
||||
.B %nA
|
||||
in the
|
||||
.B FORMATTING
|
||||
section below. Implies
|
||||
.BR \-C .
|
||||
.TP
|
||||
.B \-F, \-\-format FORMAT
|
||||
Ignore the options
|
||||
.BR \-p ,
|
||||
.BR \-t ,
|
||||
.BR \-e ,
|
||||
.BR \-r ,
|
||||
.BR \-a ,
|
||||
.BR \-b ,
|
||||
.BR \-T ,
|
||||
and
|
||||
.BR \-A ,
|
||||
and instead use the format string
|
||||
.B FORMAT
|
||||
to determine the output format. See the
|
||||
.B FORMATTING
|
||||
section below.
|
||||
.TP
|
||||
.B \-n, \-\-numeric
|
||||
Numeric output. Instead of giving a visual indication of progress,
|
||||
.B @PACKAGE@
|
||||
will give an integer percentage, one per line, on standard error, suitable
|
||||
for piping (via convoluted redirection) into
|
||||
.BR dialog (1).
|
||||
Note that
|
||||
.B \-f
|
||||
is not required if
|
||||
.B \-n
|
||||
is being used.
|
||||
.TP
|
||||
.B ""
|
||||
Note that if
|
||||
.B \-\-numeric
|
||||
is in use, then adding
|
||||
.B \-\-bytes
|
||||
will cause the number of bytes processed so far to be output instead of a
|
||||
percentage; if
|
||||
.B \-\-line\-mode
|
||||
is also in use as well as
|
||||
.B \-\-bytes
|
||||
and
|
||||
.BR \-\-numeric ,
|
||||
then instead of bytes or a percentage, the number of lines
|
||||
so far is output. And finally, if
|
||||
.B \-\-timer
|
||||
is added to
|
||||
.BR \-\-numeric ,
|
||||
then each output line is prefixed with the elapsed time
|
||||
so far, as a decimal number of seconds.
|
||||
.TP
|
||||
.B \-q, \-\-quiet
|
||||
No output. Useful if the
|
||||
.B \-L
|
||||
option is being used on its own to just limit the transfer rate of a pipe.
|
||||
|
||||
|
||||
.SH OUTPUT MODIFIERS
|
||||
.TP
|
||||
.B \-W, \-\-wait
|
||||
Wait until the first byte has been transferred before showing any progress
|
||||
information or calculating any ETAs. Useful if the program you are piping to
|
||||
or from requires extra information before it starts, eg piping data into
|
||||
.BR gpg (1)
|
||||
or
|
||||
.BR mcrypt (1)
|
||||
which require a passphrase before data can be processed.
|
||||
.TP
|
||||
.B \-D, \-\-delay-start SEC
|
||||
Wait until
|
||||
.B SEC
|
||||
seconds have passed before showing any progress information, for example in
|
||||
a script where you only want to show a progress bar if it starts taking a
|
||||
long time. Note that this can be a decimal such as 0.5.
|
||||
.TP
|
||||
.B \-s SIZE, \-\-size SIZE
|
||||
Assume the total amount of data to be transferred is
|
||||
.B SIZE
|
||||
bytes when calculating percentages and ETAs. The same suffixes of "k", "m"
|
||||
etc can be used as with
|
||||
.BR -L .
|
||||
.TP
|
||||
.B ""
|
||||
If
|
||||
.B SIZE
|
||||
starts with
|
||||
.BR "@" ,
|
||||
the size of file whose name follows the
|
||||
.B @
|
||||
will be used.
|
||||
.TP
|
||||
.B ""
|
||||
Note that
|
||||
.B \-\-size
|
||||
has no effect if used with
|
||||
.B -d PID
|
||||
to watch all file descriptors of a process, but will work with
|
||||
.BR "-d PID:FD" .
|
||||
.TP
|
||||
.B \-l, \-\-line\-mode
|
||||
Instead of counting bytes, count lines (newline characters). The progress
|
||||
bar will only move when a new line is found, and the value passed to the
|
||||
.B \-s
|
||||
option will be interpreted as a line count. Note that file sizes are not
|
||||
automatically calculated when this option is used, to avoid having to read
|
||||
all files twice.
|
||||
.TP
|
||||
.B \-0, \-\-null
|
||||
Count lines as null terminated. This option implies \-\-line\-mode.
|
||||
.TP
|
||||
.B \-i SEC, \-\-interval SEC
|
||||
Wait
|
||||
.B SEC
|
||||
seconds between updates. The default is to update every second.
|
||||
Note that this can be a decimal such as 0.1.
|
||||
.TP
|
||||
.B \-m SEC, \-\-average-rate-window SEC
|
||||
Compute current average rate over a
|
||||
.B SEC
|
||||
seconds window for average rate and ETA calculations (default 30s).
|
||||
.TP
|
||||
.B \-w WIDTH, \-\-width WIDTH
|
||||
Assume the terminal is
|
||||
.B WIDTH
|
||||
characters wide, instead of trying to work it out (or assuming 80 if it
|
||||
cannot be guessed).
|
||||
.TP
|
||||
.B \-H HEIGHT, \-\-height HEIGHT
|
||||
Assume the terminal is
|
||||
.B HEIGHT
|
||||
rows high, instead of trying to work it out (or assuming 25 if it
|
||||
cannot be guessed).
|
||||
.TP
|
||||
.B \-N NAME, \-\-name NAME
|
||||
Prefix the output information with
|
||||
.BR NAME .
|
||||
Useful in conjunction with
|
||||
.B \-c
|
||||
if you have a complicated pipeline and you want to be able to tell different
|
||||
parts of it apart.
|
||||
.TP
|
||||
.B \-f, \-\-force
|
||||
Force output. Normally,
|
||||
.B @PACKAGE@
|
||||
will not output any visual display if standard error is not a terminal.
|
||||
This option forces it to do so.
|
||||
.TP
|
||||
.B \-c, \-\-cursor
|
||||
Use cursor positioning escape sequences instead of just using carriage
|
||||
returns. This is useful in conjunction with
|
||||
.B \-N
|
||||
(name) if you are using multiple
|
||||
.B @PACKAGE@
|
||||
invocations in a single, long, pipeline.
|
||||
|
||||
|
||||
.SH DATA TRANSFER MODIFIERS
|
||||
.TP
|
||||
.B \-L RATE, \-\-rate-limit RATE
|
||||
Limit the transfer to a maximum of
|
||||
.B RATE
|
||||
bytes per second. A suffix of "K", "M", "G", or "T" can be added to denote
|
||||
kibibytes (*1024), mebibytes, and so on.
|
||||
.TP
|
||||
.B \-B BYTES, \-\-buffer-size BYTES
|
||||
Use a transfer buffer size of
|
||||
.B BYTES
|
||||
bytes. A suffix of "K", "M", "G", or "T" can be added to denote
|
||||
kibibytes (*1024), mebibytes, and so on. The default buffer size is the
|
||||
block size of the input file's filesystem multiplied by 32 (512KiB max), or
|
||||
400KiB if the block size cannot be determined. This can be useful on
|
||||
platforms like MacOS which perform better in pipelines with specific buffer
|
||||
sizes such as 1024. Implies
|
||||
.BR \-C .
|
||||
.TP
|
||||
.B \-C, \-\-no-splice
|
||||
Never use
|
||||
.BR splice (2),
|
||||
even if it would normally be possible. The
|
||||
.BR splice (2)
|
||||
system call is a more efficient way of transferring data from or to a pipe
|
||||
than regular
|
||||
.BR read (2)
|
||||
and
|
||||
.BR write (2),
|
||||
but means that the transfer buffer may not be used. This prevents
|
||||
.B \-A
|
||||
and
|
||||
.B \-T
|
||||
from working, and makes
|
||||
.B \-B
|
||||
redundant, so using
|
||||
.BR \-A ,
|
||||
.BR \-T ,
|
||||
or
|
||||
.B \-B
|
||||
automatically switches on
|
||||
.BR \-C .
|
||||
Switching on
|
||||
.B \-C
|
||||
results in a small loss of transfer efficiency.
|
||||
(This option has no effect on systems where
|
||||
.BR splice (2)
|
||||
is unavailable).
|
||||
.TP
|
||||
.B \-E, \-\-skip-errors
|
||||
Ignore read errors by attempting to skip past the offending sections. The
|
||||
corresponding parts of the output will be null bytes. At first only a few
|
||||
bytes will be skipped, but if there are many errors in a row then the skips
|
||||
will move up to chunks of 512. This is intended to be similar to
|
||||
.B dd conv=sync,noerror
|
||||
but has not been as thoroughly tested.
|
||||
.TP
|
||||
.B ""
|
||||
Specify
|
||||
.B \-E
|
||||
twice to only report a read error once per file, instead of reporting each
|
||||
byte range skipped.
|
||||
.TP
|
||||
.B \-S, \-\-stop-at-size
|
||||
If a size was specified with
|
||||
.BR \-s ,
|
||||
stop transferring data once that many bytes have been written, instead of
|
||||
continuing to the end of input.
|
||||
.TP
|
||||
.B \-Y, \-\-sync
|
||||
After every write operation, synchronise the buffer caches to disk - see
|
||||
.BR fdatasync (2).
|
||||
This has no effect when the output is a pipe. Using
|
||||
.B \-Y
|
||||
may improve the accuracy of the progress bar when writing to a slow disk.
|
||||
.TP
|
||||
.B \-K, \-\-direct-io
|
||||
Set the
|
||||
.I O_DIRECT
|
||||
flag on all inputs and outputs, if it is available. This will minimise
|
||||
the effect of caches, at the cost of performance. Due to memory alignment
|
||||
requirements, it also may cause read or write failures with an error of
|
||||
"Invalid argument", especially if reading and writing files across a variety
|
||||
of filesystems in a single
|
||||
.B @PACKAGE@
|
||||
call. Use this option with caution.
|
||||
.TP
|
||||
.B \-d PID[:FD], \-\-watchfd PID[:FD]
|
||||
Instead of transferring data, watch file descriptor
|
||||
.B FD
|
||||
of process
|
||||
.BR PID ,
|
||||
and show its progress. The
|
||||
.B @PACKAGE@
|
||||
process will exit when
|
||||
.B FD
|
||||
either changes to a different file, changes read/write mode, or is closed;
|
||||
other data transfer modifiers - and remote control - may not be used with
|
||||
this option.
|
||||
.TP
|
||||
.B ""
|
||||
If only a
|
||||
.B PID
|
||||
is specified, then that process will be watched, and all regular files and
|
||||
block devices it opens will be shown with a progress bar. The
|
||||
.B @PACKAGE@
|
||||
process will exit when process
|
||||
.B PID
|
||||
exits.
|
||||
.TP
|
||||
.B \-R PID, \-\-remote PID
|
||||
If
|
||||
.B PID
|
||||
is an instance of
|
||||
.B @PACKAGE@
|
||||
that is already running,
|
||||
.B \-R PID
|
||||
will cause that instance to act as though it had been given
|
||||
this instance's command line instead. For example, if
|
||||
.B @PACKAGE@ -L 123K
|
||||
is running with process ID 9876, then running
|
||||
.B @PACKAGE@ -R 9876 -L 321K
|
||||
will cause it to start using a rate limit of 321KiB instead of 123KiB.
|
||||
Note that some options cannot be changed while running, such as
|
||||
.BR \-c ,
|
||||
.BR \-l ,
|
||||
.BR \-f ,
|
||||
.BR \-D ,
|
||||
.BR \-E ,
|
||||
and
|
||||
.BR \-S .
|
||||
|
||||
.SH GENERAL OPTIONS
|
||||
.TP
|
||||
.B \-P FILE, \-\-pidfile FILE
|
||||
Save the process ID of
|
||||
.B @PACKAGE@
|
||||
in
|
||||
.BR FILE .
|
||||
The file will be truncated if it already exists, and will be removed when
|
||||
.B @PACKAGE@
|
||||
exits. While
|
||||
.B @PACKAGE@
|
||||
is running, it will contain a single number - the process ID of
|
||||
.B @PACKAGE@
|
||||
- followed by a newline.
|
||||
.TP
|
||||
.B \-h, \-\-help
|
||||
Print a usage message on standard output and exit successfully.
|
||||
.TP
|
||||
.B \-V, \-\-version
|
||||
Print version information on standard output and exit successfully.
|
||||
|
||||
|
||||
.SH FORMATTING
|
||||
If the
|
||||
.B \-F
|
||||
option is given, then the output format is determined by the given format
|
||||
string. Within that string, the following sequences can be used:
|
||||
.TP
|
||||
.B %p
|
||||
Progress bar.
|
||||
Expands to fill the remaining space. Should only be specified once.
|
||||
Equivalent to
|
||||
.BR \-p .
|
||||
.TP
|
||||
.B %t
|
||||
Elapsed time. Equivalent to
|
||||
.BR \-t .
|
||||
.TP
|
||||
.B %e
|
||||
ETA as time remaining. Equivalent to
|
||||
.BR \-e .
|
||||
.TP
|
||||
.B %I
|
||||
ETA as local time of completion. Equivalent to
|
||||
.BR \-I .
|
||||
.TP
|
||||
.B %r
|
||||
Current data transfer rate. Equivalent to
|
||||
.BR \-r .
|
||||
.TP
|
||||
.B %a
|
||||
Average data transfer rate. Equivalent to
|
||||
.BR \-a .
|
||||
.TP
|
||||
.B %b
|
||||
Bytes transferred so far (or lines if
|
||||
.B \-l
|
||||
was specified). Equivalent to
|
||||
.BR \-b .
|
||||
If
|
||||
.B \-\-bits
|
||||
was specified,
|
||||
.B %b
|
||||
shows the bits transferred so far, not bytes.
|
||||
.TP
|
||||
.B %T
|
||||
Percentage of the transfer buffer in use. Equivalent to
|
||||
.BR \-T .
|
||||
Shows "{----}" if the transfer is being done with
|
||||
.BR splice (2),
|
||||
since splicing to or from pipes does not use the buffer.
|
||||
.TP
|
||||
.B %nA
|
||||
Show the last
|
||||
.B n
|
||||
bytes written (e.g.
|
||||
.B %16A
|
||||
for the last 16 bytes).
|
||||
Shows only dots if the transfer is being done with
|
||||
.BR splice (2),
|
||||
since splicing to or from pipes does not use the buffer.
|
||||
.TP
|
||||
.B %N
|
||||
Name prefix given by
|
||||
.BR -N .
|
||||
Padded to 9 characters with spaces, and suffixed with :.
|
||||
.TP
|
||||
.B %%
|
||||
A single %.
|
||||
.P
|
||||
The format string equivalent of turning on all display switches is
|
||||
.BR "\`%N %b %T %t %r %a %p %e'" .
|
||||
|
||||
|
||||
.SH COMMON SWITCHES
|
||||
Some suggested common switch combinations:
|
||||
|
||||
.TP
|
||||
.B @PACKAGE@ -ptebar
|
||||
Show a progress bar, elapsed time, estimated completion time, byte counter,
|
||||
average rate, and current rate.
|
||||
.TP
|
||||
.B @PACKAGE@ -betlap
|
||||
Show a progress bar, elapsed time, estimated completion time, line counter,
|
||||
and average rate, counting lines instead of bytes.
|
||||
.TP
|
||||
.B @PACKAGE@ -t
|
||||
Show only the elapsed time - useful as a simple timer, e.g.
|
||||
.BR "sleep 10m | pv -t" .
|
||||
.TP
|
||||
.B @PACKAGE@ -pterb
|
||||
The default behaviour: progress bar, elapsed time, estimated completion
|
||||
time, current rate, and byte counter.
|
||||
|
||||
.P
|
||||
On MacOS, it may be useful to specify
|
||||
.B -B 1024
|
||||
in a pipeline, as this may improve performance.
|
||||
|
||||
|
||||
.SH EXIT STATUS
|
||||
An exit status of 1 indicates a problem with the
|
||||
.B \-R
|
||||
or
|
||||
.B \-P
|
||||
options.
|
||||
|
||||
Any other exit status is a bitmask of the following:
|
||||
|
||||
.TP
|
||||
.B 2
|
||||
One or more files could not be accessed,
|
||||
.BR stat (2)ed,
|
||||
or opened.
|
||||
.TP
|
||||
.B 4
|
||||
An input file was the same as the output file.
|
||||
.TP
|
||||
.B 8
|
||||
Internal error with closing a file or moving to the next file.
|
||||
.TP
|
||||
.B 16
|
||||
There was an error while transferring data from one or more input files.
|
||||
.TP
|
||||
.B 32
|
||||
A signal was caught that caused an early exit.
|
||||
.TP
|
||||
.B 64
|
||||
Memory allocation failed.
|
||||
|
||||
.P
|
||||
A zero exit status indicates no problems.
|
||||
|
||||
|
||||
.SH AUTHOR
|
||||
Written by Andrew Wood, with patches submitted by various other people.
|
||||
Please see the package's ACKNOWLEDGEMENTS file for a complete list of
|
||||
contributors.
|
||||
|
||||
|
||||
.SH KNOWN PROBLEMS
|
||||
The following problems are known to exist in
|
||||
.BR @PACKAGE@ :
|
||||
.TP
|
||||
.B *
|
||||
In some versions of
|
||||
.BR bash (1)
|
||||
and
|
||||
.BR zsh (1),
|
||||
the construct
|
||||
.B <(pv filename)
|
||||
will not output any progress to the terminal when run from an interactive
|
||||
shell, due to the subprocess being run in a separate process group from the
|
||||
one that owns the terminal. In these cases, use
|
||||
.BR \-\-force .
|
||||
.P
|
||||
.TP
|
||||
.B *
|
||||
The
|
||||
.B -c
|
||||
option does not work properly on Cygwin without
|
||||
.B cygserver
|
||||
running, if started near the bottom of the screen (IPC is needed to handle
|
||||
the terminal scrolling). To fix this, start
|
||||
.B cygserver
|
||||
before using
|
||||
.BR "@PACKAGE@ -c" .
|
||||
.P
|
||||
.TP
|
||||
.B *
|
||||
The
|
||||
.B -R
|
||||
option is not available on Cygwin without
|
||||
.B cygserver
|
||||
running (SYSV IPC is needed). To fix this, start
|
||||
.B cygserver
|
||||
before running the instance of
|
||||
.B @PACKAGE@
|
||||
you want, at runtime, to change the parameters of.
|
||||
.P
|
||||
If you find any other problems, please report them.
|
||||
|
||||
|
||||
.SH REPORTING BUGS
|
||||
Report bugs in
|
||||
.B @PACKAGE@
|
||||
to pv@ivarch.com or use the contact form linked from the
|
||||
.B @PACKAGE@
|
||||
home page: <http://www.ivarch.com/programs/pv.shtml>
|
||||
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR cat (1),
|
||||
.BR dialog (1),
|
||||
.BR splice (2),
|
||||
.BR open (2)
|
||||
(for
|
||||
.IR O_DIRECT )
|
||||
|
||||
.SH LICENSE
|
||||
This is free software, distributed under the ARTISTIC 2.0 license.
|
||||
@@ -1,18 +0,0 @@
|
||||
Before releasing a new version, go through this checklist:
|
||||
|
||||
- check for patches from https://tracker.debian.org/pkg/pv
|
||||
- bump doc/VERSION
|
||||
- bump doc/lsm.in
|
||||
- check doc/NEWS.md is up to date
|
||||
- check manual is up to date
|
||||
- make indent; make indent indentclean
|
||||
- make update-po
|
||||
- make test
|
||||
- commit to repository
|
||||
- wipe build directory, re-run generate.sh and configure
|
||||
- make release MAINTAINER=<signing-user>
|
||||
- make manhtml | tidy -asxhtml | sed -e '1,/<body>/d' -e '/<\/body>/,$d'
|
||||
- update HTML for todo and news
|
||||
- copy and sign tar.gz to HTML directory (sig as both .asc and .txt)
|
||||
- submit new release to Sourceforge
|
||||
- upload HTML
|
||||
@@ -0,0 +1,152 @@
|
||||
The following people have contributed to this project, and their assistance
|
||||
is acknowledged and greatly appreciated:
|
||||
|
||||
* Antoine Beaupré <anarcat@debian.org> - Debian package maintainer
|
||||
* Kevin Coyner <kcoyner@debian.org> - previous Debian package maintainer
|
||||
* Cédric Delfosse <cedric@debian.org> - previous Debian package maintainer
|
||||
* Jakub Hrozek <jhrozek@redhat.com> - Fedora package maintainer
|
||||
* Eduardo Aguiar <eduardo.oliveira@sondabrasil.com.br> - provided Portuguese (Brazilian) translation
|
||||
* Stéphane Lacasse <stephane@gorfou.ca> - provided French translation
|
||||
* Marcos Kreinacke <public@kreinacke.com> - provided German translation
|
||||
* Bartosz Feński <fenio@o2.pl> <http://skawina.eu.org/> - provided Polish translation along with Krystian Zubel
|
||||
* Joshua Jensen - reported RPM installation bug
|
||||
* Boris Folgmann <http://www.folgmann.com/en/> - reported cursor handling bug
|
||||
* Mathias Gumz - reported NLS bug
|
||||
* Daniel Roethlisberger - submitted patch to use lockfiles for **-c** if terminal locking fails
|
||||
* Adam Buchbinder - lots of help with a Cygwin port of **-c**
|
||||
* Mark Tomich <http://metuchen.dyndns.org> - suggested **-B** option
|
||||
* Gert Menke - reported bug when piping to `dd` with a large input buffer size
|
||||
* Ville Herva <Ville.Herva@iki.fi> - informative bug report about rate limiting performance
|
||||
* Elias Pipping - patch to compile properly on Darwin 9; potential NULL deref report
|
||||
* Patrick Collison - similar patch for OS X
|
||||
* Boris Lohner - reported problem that **-L** does not complain if given non-numeric value
|
||||
* Sebastian Kayser - supplied testing for *SIGPIPE*, demonstrated internationalisation problem
|
||||
* Laszlo Ersek <http://phptest11.atw.hu/> - reported shared memory leak on *SIGINT* with **-c**
|
||||
* Phil Rutschman <http://bandgap.rsnsoft.com/> - provided a patch for fully restoring terminal state on exit
|
||||
* Henry Precheur <http://henry.precheur.org/> - reporting and suggestions for **--rate-limit** bug when rate is under 10
|
||||
* E. Rosten <http://mi.eng.cam.ac.uk/~er258/> - supplied patch for block buffering in line mode
|
||||
* Kjetil Torgrim Homme - reported compilation error with default *CFLAGS* on non-GCC compilers
|
||||
* Alexandre de Verteuil - reported bug in OS X build and supplied test environment to fix in
|
||||
* Martin Baum - supplied patch to return nonzero exit status if terminated by signal
|
||||
* Sam Nelson <http://www.siliconfuture.net/> - supplied patch to fix trailing slash on *DESTDIR*
|
||||
* Daniel Pape - reported Cygwin installation problem due to *DESTDIR*
|
||||
* Philipp Beckers - ported to the Syabas PopcornHour A-100 series
|
||||
* Henry Gebhard <hsggebhardt@googlemail.com> - supplied patches to improve SI prefixes and add **--average-rate**
|
||||
* Vladimir Kokarev, Alexander Leo - reported that exit status did not reflect file errors
|
||||
* Thomas Rachel - submitted patches for IEEE1541 (MiB suffixes), 1+e03 bug
|
||||
* Guillaume Marcais - submitted speedup patch for line mode
|
||||
* Moritz Barsnick - submitted patch for compile warning in size calculation
|
||||
* Pawel Piatek - submitted RPM and patches for AIX
|
||||
* Sami Liedes - submitted patch for **--timer** and **--bytes** with **--numeric**
|
||||
* Steven Willis - reported problem with **-R** killing non-PV remote processes
|
||||
* Vladimir Pal, Vladimir Ermakov - submitted patch which led to development of **--format** option
|
||||
* Peter Samuelson <peter@p12n.org> - submitted patch to calculate size if stdout is a block device
|
||||
* Miguel Diaz - much Cygwin help (and packaging), found narrow-terminal bug
|
||||
* Jim Salter <http://ubuntuwiki.net> - commissioned work on the **--skip-errors** option
|
||||
* Wouter Pronk - reported build problem on SCO
|
||||
* Bryan Dongray <http://www.dongrays.com> - provided patches for test scripts failing on older Red Hats
|
||||
* Zev Weiss <www.bewilderbeest.net> - provided patch to fix `splice()` not using stdin
|
||||
* Zing Shishak - provided patch for **--null** / **-0** (count null terminated lines)
|
||||
* Jacek Wielemborek <http://deetah.jogger.pl/kategorie/english> - implemented fdwatch in Python, suggested PV port; reported bug with **-l** and ETA / size; many other contributions
|
||||
* Kim Krecht - suggested buffer fill status and last bytes output display options
|
||||
* Cristian Ciupitu <http://ciupicri.github.io>, Josh Stone - pointed out file descriptor leak with helpful suggestions (Josh Stone initially noticed the missing close)
|
||||
* Jan Seda - found issue with `splice()` and *SPLICE_F_NONBLOCK* causing slowdown
|
||||
* André Stapf - pointed out formatting problem e.g. 13GB -> 13.1GB which should be shown 13.0GB -> 13.1GB; highlighted on-startup row swapping in **-c**, and suggested **--discard**; suggested making **--fineta** have a "FIN" prefix
|
||||
* Damon Harper <http://www.usrbin.ca/> - suggested **-D** / **--delay-start** option
|
||||
* Ganaël Laplanche <http://www.martymac.org> - provided patch for `lstat64()` on systems that do not support it
|
||||
* Peter Korsgaard <http://www.buildroot.net/> - provided similar patch for `lstat64()`, specifically for uClibc support; provided AIX cross-compilation patch to fix bug in **-lc128** check
|
||||
* Ralf Ramsauer <https://blog.ramses-pyramidenbau.de/> - reported bug which dropped transfer rate on terminal resize
|
||||
* Michiel Van Herwegen - reported and discussed bug with **-l** and ETA / size
|
||||
* Erkki Seppälä <http://www.inside.org/~flux/> - provided patch implementing **-I**
|
||||
* Eric A. Borisch - provided details of compatibility fix for "`%Lu`" in watchpid code
|
||||
* Jan Venekamp - reported MacOS buffer size interactions with pipes
|
||||
* Matt <https://github.com/lemonsqueeze/pv> - provided "rate-window" patches for rate calculation
|
||||
* [Filippo Valsorda](https://github.com/FiloSottile) - provided patch for stat64 issue on Apple Silicon
|
||||
* Matt Koscica, William Dillon - also reported stat64 issue on Apple Silicon
|
||||
* [Demitri Muna](https://github.com/demitri) - assisted with stat64 patch on Apple Silicon
|
||||
* Norman Rasmussen - suggested **-c** with **-d PID:FD**, reject **-N** with **-d PID**
|
||||
* Andriy Gapon, Jonathan Elchison - reported bug where "`pv /dev/zero >/dev/null &`" stops immediately
|
||||
* Marcelo Chiesa - reported unused-result warnings when compiling PV 1.6.6
|
||||
* Jered Floyd - provided patches to improve **--rate-limit**
|
||||
* Christoph Biedl - provided ETA and dynamic interval patches
|
||||
* Richard Fonfara - provided German translations for "`pv --help`"
|
||||
* Johannes Gerer <http://johannesgerer.com> - suggested that **-B** should enable **-C**
|
||||
* Sam James - provided fix for number.c build issue caused by missing stddef.h
|
||||
* Jakub Wilk <jwilk@jwilk.net> - corrected README encoding
|
||||
* Frederik Eaton - reported issue with `<()` shell constructs
|
||||
* [gray](https://github.com/gray) - reported issue with **--force** and terminal process groups, and proposed a patch
|
||||
* [Luc Gommans](https://github.com/lgommans) / https://lgms.nl/ - provided a "momentary ETA" patch
|
||||
* [ikasty](https://github.com/ikasty) - added relative filename display to **--watchfd**
|
||||
* [Michael Weiß](https://github.com/quitschbo) - corrected behaviour when not attached to a terminal
|
||||
* [christoph-zededa](https://github.com/christoph-zededa) - provided OS X support for **--watchfd**
|
||||
* [Dave Beckett](https://github.com/dajobe) - added "`@filename`" syntax to **--size**, and corrected an autoconf problem with stat64 on OS X
|
||||
* [Volodymyr Bychkovyak](https://github.com/vbychkoviak) - provided fix for rate limit behaviour with bursty traffic
|
||||
* [Nick Black](https://nick-black.com) - added **--bits** option
|
||||
* [Andrew Schulman](https://github.com/andrew-schulman) - provided reproducible example of terminal size detection issue in 1.7.17/1.7.18
|
||||
* [fuschia74](https://github.com/fuchsia74) - provided **--enable-static** patch for "`configure`"
|
||||
* [Wilhelm von Thiele](https://github.com/TurtleWilly) - assisted with OS X cleanups ([#73](https://codeberg.org/ivarch/pv/issues/73), [#74](https://codeberg.org/ivarch/pv/issues/74))
|
||||
* Matějů Miroslav, Ing. - suggested fix for ETA and elapsed time faults when suspending and resuming a machine ([#13](https://codeberg.org/ivarch/pv/issues/13))
|
||||
* Anthony DeRobertis - suggested the **--error-skip-block** option ([#37](https://codeberg.org/ivarch/pv/issues/37))
|
||||
* Benoit Pierre - provided patches for compilation without IPC support, without HAVE_STRUCT_STAT_ST_BLKSIZE, and on MacOS
|
||||
* [gustav-b](https://codeberg.org/gustav-b) - suggested percentage formatting correction ([#80](https://codeberg.org/ivarch/pv/issues/80))
|
||||
* [Thomas Bertels](https://codeberg.org/tbertels) - updated French translations ([#83](https://codeberg.org/ivarch/pv/pulls/83))
|
||||
* [kevinruddy](https://codeberg.org/kevinruddy) - added decimal units option ([#85](https://codeberg.org/ivarch/pv/pulls/85))
|
||||
* [xmort](https://codeberg.org/xmort) - added **--output** option ([#90](https://codeberg.org/ivarch/pv/pulls/90))
|
||||
* [bogiord](https://codeberg.org/bogiord) - reported the loss of output block device size detection in 1.8.10, and suggested the fix ([#91](https://codeberg.org/ivarch/pv/issues/91))
|
||||
* [eborisch](https://codeberg.org/eborisch) - provided fix for misbehaviour when used with "`zfs send`" due to treating zero sized writes (generally due to timer interruption) as end of file ([#92](https://codeberg.org/ivarch/pv/pulls/92), [#93](https://codeberg.org/ivarch/pv/pulls/93))
|
||||
* [alexanderperlis](https://codeberg.org/alexanderperlis) - provided initial support for block devices with **--size `@`FILE** ([#94](https://codeberg.org/ivarch/pv/pulls/94))
|
||||
* [jettero](https://codeberg.org/jettero) - reported double-free coredump when using **--watchfd** after 1.8.10 ([#96](https://codeberg.org/ivarch/pv/issues/96))
|
||||
* Venky.N.Iyer - suggested **--stats** ([#49](https://codeberg.org/ivarch/pv/issues/49))
|
||||
* Roland Kletzing - suggested **--rate** with **--numeric** ([#17](https://codeberg.org/ivarch/pv/issues/17))
|
||||
* [Michael Mior](https://codeberg.org/michaelmior) - suggested **--store-and-forward** ([#100](https://codeberg.org/ivarch/pv/issues/100))
|
||||
* [dbungert](https://codeberg.org/dbungert) - reported issue with *valgrind* 3.23 misreporting leaking file descriptors ([#97](https://codeberg.org/ivarch/pv/issues/97))
|
||||
* Joachim Haga - suggested showing progress in the window title ([#3](https://codeberg.org/ivarch/pv/issues/3))
|
||||
* [Martin Sarsale](https://github.com/runa) - suggested showing progress in the process title ([#4](https://codeberg.org/ivarch/pv/issues/4))
|
||||
* [2bits](https://github.com/2bits) - reported position sensing fault with **--watchfd** in 1.9.0 ([#118](https://codeberg.org/ivarch/pv/issues/118))
|
||||
* [heitbaum](https://codeberg.org/heitbaum) - assisted with cross-compilation fault introduced in 1.9.7 ([#120](https://codeberg.org/ivarch/pv/issues/120))
|
||||
* [meego](https://codeberg.org/meego) - suggested "**%nL**", the last line preview ([#121](https://codeberg.org/ivarch/pv/issues/121))
|
||||
* [Alexander Petrossian](https://github.com/neopaf) - suggested using Unicode output for a more granular progress bar, and provided the codepoints to use ([#15](https://codeberg.org/ivarch/pv/issues/15))
|
||||
* [jmealo](https://codeberg.org/jmealo) - suggested JSON progress output ([#127](https://codeberg.org/ivarch/pv/issues/127))
|
||||
* [ipaqmaster](https://codeberg.org/ipaqmaster) - investigated 100%-CPU utilisation bug when piping to a command that has exited ([#164](https://codeberg.org/ivarch/pv/issues/164))
|
||||
* Andriy Galetski, and also [thinrope](https://codeberg.org/thinrope) - suggested the "**--sparse**" option ([#45](https://codeberg.org/ivarch/pv/issues/45))
|
||||
* [KimHansen](https://codeberg.org/KimHansen) - suggested that "**--watchfd**" should keep its display when the process ends ([#81](https://codeberg.org/ivarch/pv/issues/81))
|
||||
* [njt](https://codeberg.org/njt) - suggested that "**--size** @*PATH*" should accept directories ([#179](https://codeberg.org/ivarch/pv/issues/179))
|
||||
* [mojohakase](https://codeberg.org/mojohakase) - provided fix for multiplication bug when combining "**--bits**" with "**--gauge**" ([#182](https://codeberg.org/ivarch/pv/issues/182))
|
||||
* [traq6046](https://codeberg.org/traq6046) - highlighted autoreconf issues with the repository ([#185](https://codeberg.org/ivarch/pv/issues/185))
|
||||
* [heitbaum](https://codeberg.org/heitbaum) - fixed GCC warning when using glibc 2.43 ([#180](https://codeberg.org/ivarch/pv/pulls/180))
|
||||
* [haarp](https://codeberg.org/haarp) - reported that control-C writes "^C" over the progress, and suggested a fix ([#187](https://codeberg.org/ivarch/pv/issues/187))
|
||||
* [Wolfgang Hoschek](https://codeberg.org/whoschek) - provided a fix for the endless wait if the output receiver exits before emptying the pipe ([#189](https://codeberg.org/ivarch/pv/issues/189))
|
||||
* [oech3](https://codeberg.org/oech3) - suggested and tested performance improvements using `splice()` in more situations on Linux ([#188](https://codeberg.org/ivarch/pv/issues/188), [#191](https://codeberg.org/ivarch/pv/issues/191), [#192](https://codeberg.org/ivarch/pv/issues/192))
|
||||
* [Barak A. Pearlmutter](https://codeberg.org/barak) - suggested that "**--rate-limit**" should accept non-integer values ([#193](https://codeberg.org/ivarch/pv/issues/193))
|
||||
* [dirkmueller](https://codeberg.org/dirkmueller) - fixed the potential for stdout closure under a combination of error conditions in **--monitor** mode ([#201](https://codeberg.org/ivarch/pv/pulls/201))
|
||||
* [InkstainTheBat](https://codeberg.org/InkstainTheBat) - suggested ConEmu OSC 9;4 support ([#202](https://codeberg.org/ivarch/pv/issues/202))
|
||||
|
||||
Translations provided through [Codeberg Weblate](https://translate.codeberg.org/projects/pv/):
|
||||
|
||||
* **Czech**
|
||||
* [mmatous](https://translate.codeberg.org/user/mmatous/) (135)
|
||||
* **Finnish**
|
||||
* [artnay](https://translate.codeberg.org/user/artnay/) (65)
|
||||
* [Ricky-Tigg](https://translate.codeberg.org/user/Ricky-Tigg/) (66)
|
||||
* **French**
|
||||
* anonymous suggestions (7)
|
||||
* [milimarg](https://codeberg.org/milimarg) (13)
|
||||
* [Maxi_Mega](https://translate.codeberg.org/user/Maxi_Mega/) (11)
|
||||
* **German**
|
||||
* [Hartmut Goebel](https://translate.codeberg.org/user/htgoebel/) (77)
|
||||
* [m0yellow](https://translate.codeberg.org/user/m0yellow/) (9)
|
||||
* [Benny](https://translate.codeberg.org/user/Benny/) (7)
|
||||
* [kre](https://translate.codeberg.org/user/kre/) (2)
|
||||
* [fnetX](https://translate.codeberg.org/user/fnetX/) (1)
|
||||
* **Italian**
|
||||
* [ldm](https://translate.codeberg.org/user/ldm/) (27)
|
||||
* **Polish**
|
||||
* [coralpink](https://translate.codeberg.org/user/coralpink/) (122)
|
||||
* **Russian**
|
||||
* [0ko](https://translate.codeberg.org/user/0ko/) (157)
|
||||
* [some_user](https://translate.codeberg.org/user/some_user/) (7)
|
||||
* **Turkish**
|
||||
* [omerdduran](https://translate.codeberg.org/user/omerdduran/) (129)
|
||||
* [Oğuz Ersen](https://codeberg.org/ersen) (8)
|
||||
|
||||
---
|
||||
+674
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
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:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
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
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,219 @@
|
||||
# Notes for developers and translators
|
||||
|
||||
The following _configure_ options will be of interest to developers and
|
||||
translators:
|
||||
|
||||
* **--enable-debugging** - build in debugging support
|
||||
* **--enable-profiling** - build in support for profiling
|
||||
|
||||
These targets are available when running _make_:
|
||||
|
||||
* "`make analyse`" - run _splint_ and _flawfinder_ on all C source files
|
||||
|
||||
|
||||
## Debugging and profiling support
|
||||
|
||||
When "`./configure --enable-debugging`" is used, the _pv_ produced by _make_
|
||||
will support an extra option, "**--debug FILE**", which will cause debugging
|
||||
output to be written to *FILE*. This is not recommended for production
|
||||
builds due to the extra processing it introduces, and the potential size of
|
||||
the output.
|
||||
|
||||
Within the code, "**debug()**" is used in a similar way to "**printf()**".
|
||||
It will automatically include the calling function, source file, and line
|
||||
number, so they don't need to be included in the parameters. When debugging
|
||||
support is not enabled, it evaluates to a null statement.
|
||||
|
||||
This does mean that if you call "**debug()**", make sure it has no side
|
||||
effects, as they won't be present in builds without debugging support.
|
||||
|
||||
Builds produced after "`./configure --enable-profiling`" will write profile
|
||||
data when run, to be used with _gprof_. See "`man gprof`" for details.
|
||||
Please note that the memory safety checks will fail with profiling enabled.
|
||||
|
||||
|
||||
## Source code analysis
|
||||
|
||||
Running "`make analyse`" runs _splint_ and _flawfinder_ on all C sources,
|
||||
writing the output of both programs to files named _"*.e"_ for each _"*.c"_.
|
||||
|
||||
There are no dependency rules set up for these _".e"_ files, so if a header
|
||||
file is altered, manually remove the relevant _".e"_ files, or update the
|
||||
timestamp of the relevant _".c"_ files, before running "`make analyse`"
|
||||
again.
|
||||
|
||||
The goal is for all C source files to generate zero warnings from either
|
||||
tool.
|
||||
|
||||
Wherever warnings are disabled by annotations to the source, there should be
|
||||
associated commentary nearby explaining the rationale behind it, and any
|
||||
assumptions made. This is so that there can be some assurance that the
|
||||
issue highlighted by the analyser has been considered properly, as well as
|
||||
documenting anything that might need further work if the surrounding code is
|
||||
altered in future.
|
||||
|
||||
|
||||
## Translation notes
|
||||
|
||||
Translators can use the Weblate instance hosted by Codeberg:
|
||||
[https://translate.codeberg.org/projects/pv/](https://translate.codeberg.org/projects/pv/)
|
||||
|
||||
If you don't see your language listed, raise an issue on the issue tracker
|
||||
(or just email the maintainer) asking for it to be added.
|
||||
|
||||
Alternatively, read on for details of how to maintain the translations
|
||||
directly within the source tree.
|
||||
|
||||
The message catalogues used to translate program messages into other
|
||||
languages are in the _"po/"_ directory, named _"xx.po"_, where _"xx"_
|
||||
is the ISO 639-1 2-letter language code, such as "**fr**" for French.
|
||||
|
||||
Each of these files contains lines like this:
|
||||
|
||||
#: src/pv/cursor.c:85
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "erro ao ler o nome do terminal"
|
||||
|
||||
The comment line, starting _"#"_, shows the source filename and line number
|
||||
at which this message can be found. The _"msgid"_ is the original message
|
||||
in the program, in English. The _"msgstr"_ is the translated text.
|
||||
|
||||
It is the _"msgstr"_ lines which need to be updated by translators.
|
||||
|
||||
Message catalogue files should all be encoded as UTF-8.
|
||||
|
||||
After making a change to a _".po"_ file, test it by compiling it and
|
||||
installing to a temporary location, like this:
|
||||
|
||||
./configure --enable-debugging --prefix=/tmp/yourtest
|
||||
make clean
|
||||
make install
|
||||
localedef -f UTF-8 -i de_DE /tmp/yourtest/share/locale/de_DE.UTF-8
|
||||
bash
|
||||
export LOCPATH=/tmp/yourtest/share/locale
|
||||
export LC_ALL=de_DE.UTF-8
|
||||
export LANGUAGE=de_DE
|
||||
/tmp/yourtest/bin/pv --help
|
||||
exit
|
||||
|
||||
Replace "**--help**" with whatever is appropriate for your test. In this
|
||||
example, the language being tested is _"de"_ (German), on a system which is
|
||||
running with UTF-8 support.
|
||||
|
||||
In the example above, a new shell is started by typing "`bash`" so that
|
||||
after your tests, "`exit`" will return you to your previous shell with your
|
||||
language settings intact.
|
||||
|
||||
Note that at the start, you have to re-run _configure_ with "**--prefix**"
|
||||
rather than using "`make DESTDIR=...`", because the locale directory is set
|
||||
at compile time. Also, on Debian at least, both the environment variables
|
||||
_"LC_ALL"_ and _"LANGUAGE"_ must be set.
|
||||
|
||||
To find untranslated strings in a language that's already supported but
|
||||
which you can help with gaps in, use this command:
|
||||
|
||||
msgattrib --untranslated < po/fr.po
|
||||
|
||||
replacing _"po/fr.po"_ as appropriate.
|
||||
|
||||
To add a new language, create the new message catalogue file under _"po/"_
|
||||
by copying _"po/pv.pot"_ to _"po/xx.po"_, where _"xx"_ is the language code,
|
||||
and adjusting it. The _".pot"_ file is generated automatically by _make_.
|
||||
|
||||
Next, add the language code to _"po/LINGUAS"_ - this is a list of the
|
||||
2-letter codes of the supported languages.
|
||||
|
||||
Finally, run "`./config.status`" and "`make -C po update-po`".
|
||||
|
||||
When the source code is updated, running "`make -C po update-po`" will
|
||||
update the _"pv.pot"_ file so that it lists where all the messages are in
|
||||
the source. It will also use _msgmerge_ to update all of the _".po"_ files
|
||||
from the updated _"pv.pot"_ file. After doing this, look for missing
|
||||
translations (empty _"msgstr"_ lines) or translations marked as "fuzzy", as
|
||||
these will need to be corrected by translators.
|
||||
|
||||
|
||||
## Benchmarking
|
||||
|
||||
The "`docs/benchmark-pv-transfers.sh`" script, introduced in
|
||||
[#198](https://codeberg.org/ivarch/pv/issues/198), is used to check that new
|
||||
changes to **pv** aren't making it less efficient at transferring data. Run
|
||||
it with the **--help** option for a summary of its options.
|
||||
|
||||
In _benchmark_ mode, it takes multiple rounds of measurements of the
|
||||
transfer rate using various different transfer options. The mean (μ) and
|
||||
standard deviation (σ) of each measurement is produced at the end of the
|
||||
run. All data is written to the standard output - pipe to "`tee OUTPUT`" to
|
||||
write to a file _OUTPUT_ while still displaying it on the terminal.
|
||||
|
||||
Either a specific **pv** binary can be benchmarked (with the **-p** option),
|
||||
or multiple **pv** versions can be benchmarked in a single call, each one
|
||||
counting as an individual run (with the **-d** option, pointing to a
|
||||
directory containing _tar.gz_ source archives).
|
||||
|
||||
Transfer rate measurements use up to two test files, the size of which can
|
||||
be overridden by the **-s** option, and some measurements will transfer and
|
||||
discard zeros from _/dev/zero_, the amount of which can be overridden with
|
||||
the **-z** option.
|
||||
|
||||
The measured rates may vary significantly due to external factors such as
|
||||
system load, so multiple measurement rounds (the **-r** option) are
|
||||
recommended per run.
|
||||
|
||||
In _analyse_ mode, the results of multiple runs are read from standard
|
||||
input, and a report is produced that shows how each measurement differs
|
||||
between runs.
|
||||
|
||||
If the input data is from multiple versions of **pv**, the differences
|
||||
between versions will be compared; otherwise, the differences between
|
||||
individual runs will be compared. The **-c** option overrides this.
|
||||
|
||||
When re-using data from multiple runs, the **-f** option causes the report
|
||||
to only show the differences between the last two runs (or versions).
|
||||
|
||||
The **-t** option produces a terse report that is more machine-readable.
|
||||
|
||||
In _measurements_ mode, a list of all of the measurement types is produced.
|
||||
Each type of measurement has an associated ID - these IDs can be passed to
|
||||
the benchmark mode to only run a subset of the measurements in that run.
|
||||
|
||||
|
||||
## Release checklist
|
||||
|
||||
The package maintainer should run through these steps for a new release:
|
||||
|
||||
* Check for patches and bug reports:
|
||||
* <https://codeberg.org/ivarch/pv/issues>
|
||||
* <https://tracker.debian.org/pkg/pv>
|
||||
* <https://launchpad.net/ubuntu/+source/pv>
|
||||
* <https://archlinux.org/packages/extra/x86_64/pv/>
|
||||
* <https://packages.gentoo.org/packages/sys-apps/pv>
|
||||
* <https://cvsweb.openbsd.org/ports/sysutils/pv/>
|
||||
* <https://packages.fedoraproject.org/pkgs/pv/pv/>
|
||||
* Check for translation updates <https://translate.codeberg.org/projects/pv>
|
||||
* Run "`make indent; make indent indentclean check`"
|
||||
* Check that _po/POTFILES.in_ is up to date
|
||||
* Run "`make -C po update-po`"
|
||||
* Run "`make analyse`" and see whether remaining warnings can be addressed
|
||||
* Version bump and documentation checks:
|
||||
* Update the version in _configure.ac_ and _docs/NEWS.md_
|
||||
* Check that _docs/NEWS.md_ is up to date
|
||||
* Check that the manual _docs/pv.1_ is up to date
|
||||
* Run "`make docs/pv.1.md`" and, if using VPATH, copy the result to the source directory
|
||||
* Check that the year displayed by _src/main/version.c_ is correct
|
||||
* Ensure everything has been committed to the repository
|
||||
* Run "`autoreconf -is`" in the source directory
|
||||
* Consistency and build checks:
|
||||
* Wipe the build directory, and run _configure_ there
|
||||
* Run "`make distcheck`"
|
||||
* Run "`./configure && make check`" on all test systems including Cygwin, using the `tar.gz` that was just created
|
||||
* Run a cross-compilation check
|
||||
* Run "`make release MAINTAINER=<signing-user>`"
|
||||
* Update the project web site:
|
||||
* Copy the release _.tar.gz_, _.txt_, and _.asc_ files to the web site
|
||||
* Use "`pandoc --from markdown --to html`" to convert the news and manual to HTML
|
||||
* Update the news and manual on the web site
|
||||
* Update the version numbers on the web site
|
||||
* Update the package index on the web site
|
||||
* Create a new release in the repository, and apply the associated tag
|
||||
|
||||
+666
@@ -0,0 +1,666 @@
|
||||
### UNRELEASED
|
||||
|
||||
* *feature:* new **--format** string **%{progress-conemu}**, and option **--conemu**, to show progress in the terminal title tab on terminals with ConEmu OSC 9;4 support ([#202](https://codeberg.org/ivarch/pv/issues/202))
|
||||
* *cleanup:* eliminate potential for closure of standard output under a combination of error conditions when using **--monitor** mode ([#201](https://codeberg.org/ivarch/pv/pulls/201))
|
||||
* *i18n:* Italian translations added
|
||||
* *i18n:* Russian translations updated
|
||||
* *i18n:* empty Romanian message catalogue added, awaiting translations
|
||||
|
||||
### 1.11.0 - 11 June 2026
|
||||
|
||||
* *feature:* new **--monitor** option to run a command and watch its input, output, or both ([#67](https://codeberg.org/ivarch/pv/issues/67))
|
||||
* *feature:* allow decimal values for **--rate-limit** ([#193](https://codeberg.org/ivarch/pv/issues/193))
|
||||
* *feature:* extend the **--format** string **%T**/**%{buffer-percent}** to indicate the transfer method when the buffer isn't being used
|
||||
* *performance:* insert an intermediate input pipe where it would allow `splice()` to be used in more circumstances ([#188](https://codeberg.org/ivarch/pv/issues/188))
|
||||
* *performance:* use `copy_file_range`(2) when the input and output are both regular files ([#196](https://codeberg.org/ivarch/pv/issues/196))
|
||||
* *performance:* improve **--discard** performance by splicing to /dev/null internally ([#191](https://codeberg.org/ivarch/pv/issues/191))
|
||||
* *fix:* report signal interrupts on a new line, so that control-C doesn't write "^C" over the progress ([#187](https://codeberg.org/ivarch/pv/issues/187))
|
||||
* *fix:* prevent an endless wait if there is unread data in the output pipe when its reader terminates ([#189](https://codeberg.org/ivarch/pv/issues/189))
|
||||
* *fix:* prevent `splice()` from falling back to `read()` when using **--rate-limit**
|
||||
* *fix:* stop spliced transfers requiring two EOFs when the input is a terminal
|
||||
* *fix:* add timer interrupt to spliced transfers to avoid progress display lockup when the receiver stalls
|
||||
* *fix:* exit with an error if the PID file given to **--pidfile** cannot be replaced
|
||||
* *fix:* correct the **--help** word wrapping on very small terminals
|
||||
* *i18n:* Polish translations updated
|
||||
* *i18n:* Finnish translations updated
|
||||
* *i18n:* German translations updated
|
||||
* *i18n:* French translations updated
|
||||
* *i18n:* partial draft of Georgian translations added
|
||||
* *i18n:* removed empty unmaintained translation catalogue for Spanish
|
||||
* *cleanup:* fix GCC warning when using glibc 2.43 ([#180](https://codeberg.org/ivarch/pv/pulls/180))
|
||||
* *cleanup:* fix warning in pv_remote_check() stub on OpenBSD
|
||||
* *cleanup:* use dynamic line buffers for **--watchfd** process lookups
|
||||
* *cleanup:* replace the blanket 100,000-hour clamp on displayed times with a million days for timer and ETA, and 7,000 years for estimated finish time, on 64-bit systems
|
||||
* *cleanup:* use rounding when calculating ETA, and avoid integer overflows, particularly on 32-bit systems
|
||||
* *cleanup:* standardise the error reporting mechanism
|
||||
* *cleanup:* improve code comments
|
||||
|
||||
### 1.10.5 - 22 March 2026
|
||||
|
||||
* *fix:* when using **--bits** with **--gauge**, don't incorrectly multiply the rate twice ([#182](https://codeberg.org/ivarch/pv/issues/182))
|
||||
|
||||
### 1.10.4 - 8 March 2026
|
||||
|
||||
* *fix:* when using **--size @PATH**, *PATH* can be a directory, and the total size of all files within it will be used ([#179](https://codeberg.org/ivarch/pv/issues/179))
|
||||
|
||||
### 1.10.3 - 15 December 2025
|
||||
|
||||
* *fix:* stop truncating the process title set by **--extra-display**
|
||||
|
||||
### 1.10.2 - 22 November 2025
|
||||
|
||||
* *i18n:* Finnish translations updated
|
||||
* *cleanup:* adjust valgrind suppressions so memory safety tests work on LTO builds ([#174](https://codeberg.org/ivarch/pv/issues/174)/[Debian bug 1121157](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1121157))
|
||||
|
||||
### 1.10.1 - 12 November 2025
|
||||
|
||||
* *fix:* correct **--watchfd** memory allocation error when given multiple arguments ([#170](https://codeberg.org/ivarch/pv/issues/170))
|
||||
|
||||
### 1.10.0 - 7 November 2025
|
||||
|
||||
* *feature:* new **--query** option to show the transfer status of another running **pv** ([#101](https://codeberg.org/ivarch/pv/issues/101))
|
||||
* *fix:* make the timers work consistently in **--watchfd** if paused and resumed ([#169](https://codeberg.org/ivarch/pv/issues/169))
|
||||
|
||||
### 1.9.44 - 18 October 2025
|
||||
|
||||
* *feature:* new **--sparse** option to write sparse output ([#45](https://codeberg.org/ivarch/pv/issues/45))
|
||||
* *fix:* don't clear the **--watchfd** display when the watched process ends ([#81](https://codeberg.org/ivarch/pv/issues/81))
|
||||
|
||||
### 1.9.42 - 11 October 2025
|
||||
|
||||
* *feature:* permit multiple arguments to **--watchfd** ([#12](https://codeberg.org/ivarch/pv/issues/12))
|
||||
* *feature:* new "**=NAME**" syntax for **--watchfd** to watch processes by name using **pgrep**(1) ([#95](https://codeberg.org/ivarch/pv/issues/95))
|
||||
* *feature:* new "**@LISTFILE**" syntax for **--watchfd** to watch processes listed in a file
|
||||
* *fix:* improve support for changing the format of a **--watchfd** process with **--remote**
|
||||
* *fix:* don't read more than **--size** bytes when using **--stop-at-size** ([#166](https://codeberg.org/ivarch/pv/issues/166))
|
||||
* *fix:* transfer nothing if **--stop-at-size** is given a **--size** of 0 ([#166](https://codeberg.org/ivarch/pv/issues/166))
|
||||
* *i18n:* Finnish translation stub added
|
||||
* *i18n:* Turkish translations updated
|
||||
|
||||
### 1.9.34 - 26 July 2025
|
||||
|
||||
* *fix:* prevent tight loop consuming CPU when waiting for a partially filled output pipe to be drained ([#164](https://codeberg.org/ivarch/pv/issues/164))
|
||||
* *fix:* correct a memory handling fault when using **--bar-style** with **--watchfd** ([#163](https://codeberg.org/ivarch/pv/issues/163))
|
||||
* *i18n:* French translations updated
|
||||
|
||||
### 1.9.31 - 28 January 2025
|
||||
|
||||
* *feature:* the **--format** option can now be used with **--numeric** for customised numeric output, such as JSON ([#127](https://codeberg.org/ivarch/pv/issues/127))
|
||||
* *i18n:* German translations updated
|
||||
* *i18n:* Polish translations updated
|
||||
* *i18n:* Russian translations updated
|
||||
|
||||
### 1.9.27 - 12 January 2025
|
||||
|
||||
* *fix:* turn off IPC support if _sys/shm.h_ is not available, for compilation on Termux
|
||||
* *fix:* bypass valgrind checks on ARM by default due to false positives
|
||||
|
||||
### 1.9.25 - 22 December 2024
|
||||
|
||||
* *fix:* test failure of **--watchfd** on macOS corrected ([#124](https://codeberg.org/ivarch/pv/issues/124))
|
||||
|
||||
### 1.9.24 - 19 December 2024
|
||||
|
||||
* *feature:* new **--format** sequences for graphical progress bars - "**%{bar-block}**", "**%{bar-granular}**", and "**%{bar-shaded}**" ([#15](https://codeberg.org/ivarch/pv/issues/15))
|
||||
* *feature:* new **--format** sequence "**%{sgr:colour,...}**" to use ECMA-48 Select Graphic Rendition codes to add colours
|
||||
* *feature:* new **--bar-style** option to change the default bar style ([#15](https://codeberg.org/ivarch/pv/issues/15))
|
||||
* *feature:* allow decimal values such as "1.5G" with "**--size**", "**--rate-limit**", "**--buffer-size**", and "**error-skip-block**" ([#35](https://codeberg.org/ivarch/pv/issues/35))
|
||||
* *cleanup:* improve progress bar granularity on wide displays by internally tracking the transfer percentage as a decimal number
|
||||
* *cleanup:* correct detection of **--remote** usability on GNU Hurd
|
||||
* *cleanup:* reduce likelihood of race conditions in tests when running on slow systems
|
||||
* *cleanup:* reduce memory footprint
|
||||
* *docs:* simplified the synopsis section of the manual
|
||||
|
||||
### 1.9.15 - 8 December 2024
|
||||
|
||||
* *feature:* new **--format** sequence "**%nL**", showing the most recent line written ([#121](https://codeberg.org/ivarch/pv/issues/121))
|
||||
* *feature:* each **--format** sequence now has a more readable equivalent name, for example "**%r**" can be written as "**%{rate}**"
|
||||
* *feature:* new **--format** sequences "**%{progress-bar-only}**" and "**%{progress-amount-only}**"
|
||||
* *fix:* allow **--format** to include "%nA" more than once, with different "n" values ([#122](https://codeberg.org/ivarch/pv/issues/122))
|
||||
* *fix:* allow **--format** to include "%p" more than once, with optional width prefix
|
||||
* *fix:* calculate width correctly when wide characters are in **--format** strings
|
||||
* *fix:* add _configure_ script fallback for **--remote** check when cross-compiling ([#120](https://codeberg.org/ivarch/pv/issues/120))
|
||||
* *fix:* allow **extra-display** to be changed by **--remote** ([#123](https://codeberg.org/ivarch/pv/issues/123))
|
||||
* *cleanup:* refactored display formatters into separate functions
|
||||
* *cleanup:* improve format parser handling of dangling or invalid "%" sequences
|
||||
|
||||
### 1.9.7 - 2 December 2024
|
||||
|
||||
* *feature:* new **--extra-display** option to update window and process titles ([#3](https://codeberg.org/ivarch/pv/issues/3), [#4](https://codeberg.org/ivarch/pv/issues/4))
|
||||
* *fix:* correct failure to report file positions in **--watchfd** ([#118](https://codeberg.org/ivarch/pv/issues/118))
|
||||
* *i18n:* Russian translations added
|
||||
* *cleanup:* tests added for **--watchfd** ([#10](https://codeberg.org/ivarch/pv/issues/10))
|
||||
* *cleanup:* worked around file descriptor leak false positives in valgrind 3.23 ([#97](https://codeberg.org/ivarch/pv/issues/97))
|
||||
* *cleanup:* cleared all *shellcheck* warnings in the test scripts
|
||||
* *cleanup:* check at compile-time whether **--remote** is going to be usable ([#119](https://codeberg.org/ivarch/pv/issues/119))
|
||||
|
||||
### 1.9.0 - 15 October 2024
|
||||
|
||||
* *feature:* new **--store-and-forward** option to read input to a file first, then write it to the output ([#100](https://codeberg.org/ivarch/pv/issues/100))
|
||||
* *feature:* new **--stats** option to show transfer stats at the end, like "`ping`" ([#49](https://codeberg.org/ivarch/pv/issues/49))
|
||||
* *feature:* **--rate** can now be used with **--numeric** ([#17](https://codeberg.org/ivarch/pv/issues/17))
|
||||
* *feature:* **--gauge** with **--progress** to show rate gauge when size is unknown ([#46](https://codeberg.org/ivarch/pv/issues/46))
|
||||
* *i18n:* comprehensive German translations update
|
||||
* *i18n:* comprehensive Polish translations update
|
||||
* *i18n:* complete Turkish translations added
|
||||
* *i18n:* complete Czech translations added
|
||||
* *i18n:* updates to French translations
|
||||
* *fix:* resume stopped pipelines when running in the background (part of [#56](https://codeberg.org/ivarch/pv/issues/56))
|
||||
* *fix:* inspect the output pipe buffer to give a more accurate progress indicator of how much the next command has consumed
|
||||
* *fix:* prefix completion time (**--fineta**) with *FIN* rather than *ETA* ([#43](https://codeberg.org/ivarch/pv/issues/43))
|
||||
* *fix:* surround average rate (**--average-rate**) with brackets rather than square brackets
|
||||
* *fix:* correct a memory leak in **--watchfd PID**
|
||||
* *fix:* make **--direct-io** work correctly with **--output** instead of assuming stdout
|
||||
* *fix:* call `posix_fadvise()` on every input, not just the first one
|
||||
* *fix:* write UTC timestamps in debugging mode to avoid lockups in signal handlers
|
||||
* *security:* added a signed *MANIFEST* file to releases
|
||||
* *cleanup:* removed TODO.md, since it's just an outdated copy of the issue tracker
|
||||
* *cleanup:* re-ordered structure members to reduce padding
|
||||
* *cleanup:* improved readability of *SIGTTOU* handling code
|
||||
* *cleanup:* refactored to separate display, transfer, and calculation more cleanly
|
||||
* *cleanup:* instead of moving stderr when backgrounded, set a suspend-output flag
|
||||
|
||||
### 1.8.14 - 7 September 2024
|
||||
|
||||
* *fix:* correct double-free on exit when using **--watchfd** ([#96](https://codeberg.org/ivarch/pv/issues/96)) reported by [jettero](https://codeberg.org/jettero)
|
||||
|
||||
### 1.8.13 - 18 August 2024
|
||||
|
||||
* *feature:* when using **--size @FILE**, *FILE* can be a block device, and its size will be used (pull request [#94](https://codeberg.org/ivarch/pv/pulls/94)) supplied by [alexanderperlis](https://codeberg.org/alexanderperlis)
|
||||
|
||||
### 1.8.12 - 18 July 2024
|
||||
|
||||
* *fix:* correct the detection of output block device size that was broken in 1.8.10 ([#91](https://codeberg.org/ivarch/pv/issues/91))
|
||||
* *fix:* do not treat a zero/interrupted write as an end of file (pull requests [#92](https://codeberg.org/ivarch/pv/pulls/92) and [#93](https://codeberg.org/ivarch/pv/pulls/93))
|
||||
|
||||
### 1.8.10 - 15 June 2024
|
||||
|
||||
* *feature:* new **--output** option to write to a file instead of standard output (pull request [#90](https://codeberg.org/ivarch/pv/pulls/90)) supplied by [xmort](https://codeberg.org/xmort)
|
||||
|
||||
### 1.8.9 - 21 April 2024
|
||||
|
||||
* *feature:* new **--si** option to display and interpret size suffixes in multiples of 1000 rather than 1024 (pull request [#85](https://codeberg.org/ivarch/pv/pulls/85)) supplied by [kevinruddy](https://codeberg.org/kevinruddy)
|
||||
* *fix:* continue producing progress output when the output is blocking writes ([#34](https://codeberg.org/ivarch/pv/issues/34), [#86](https://codeberg.org/ivarch/pv/issues/86), [#87](https://codeberg.org/ivarch/pv/issues/87))
|
||||
* *fix:* honour the *TMPDIR* / *TMP* environment variables again, rather than hard-coding "`/tmp`", when using a terminal lock file (originally removed in 1.8.0) ([#88](https://codeberg.org/ivarch/pv/issues/88))
|
||||
* *i18n:* corrections and missing strings added to French translations (pull request [#83](https://codeberg.org/ivarch/pv/pulls/83)) supplied by [Thomas Bertels](https://codeberg.org/tbertels)
|
||||
|
||||
### 1.8.5 - 19 November 2023
|
||||
|
||||
* *fix:* corrected percentage formatting so it doesn't jump from 2 to 3 characters wide at 100% ([#80](https://codeberg.org/ivarch/pv/issues/80))
|
||||
* *fix:* replaced **--remote** mechanism, using a temporary file instead of SysV IPC, so it can work reliably even when there are multiple PV instances
|
||||
* *fix:* corrected compilation failure when without IPC support
|
||||
* *security:* addressed all issues highlighted by the software auditing tools "`splint`" and "`flawfinder`" (see "`make analyse`") ([#77](https://codeberg.org/ivarch/pv/issues/77))
|
||||
* *cleanup:* compilation warnings fixed on non-IPC and MacOS systems
|
||||
|
||||
### 1.8.0 - 24 September 2023
|
||||
|
||||
#### Features
|
||||
|
||||
* *feature:* new **--discard** option to discard input as if writing to */dev/null* ([#42](https://codeberg.org/ivarch/pv/issues/42))
|
||||
* *feature:* new **--error-skip-block** option to make **--skip-errors** skip whole blocks ([#37](https://codeberg.org/ivarch/pv/issues/37))
|
||||
* *feature:* use `posix_fadvise()` like `cat`(1) does, to improve efficiency ([#39](https://codeberg.org/ivarch/pv/issues/39))
|
||||
* *feature:* new **--enable-static** option to "`configure`" for static builds ([#75](https://codeberg.org/ivarch/pv/pulls/75))
|
||||
|
||||
#### Security
|
||||
|
||||
* *security:* with **--pidfile**, write to a temporary file and rename it into place, to improve security
|
||||
* *security:* keep self-contained copies of name and format string in PV internal state for memory safety
|
||||
* *security:* ignore *TMP* / *TMPDIR* environment variables when using a terminal lock file
|
||||
|
||||
#### Fixes
|
||||
|
||||
* *fix:* only report errors about missing files when starting to transfer from them, not while calculating size, and behave more like `cat`(1) by skipping them and moving on
|
||||
* *fix:* auto-calculate total line count with **--line-mode** when all inputs are regular files
|
||||
* *fix:* use `clock_gettime()` in ETA calculation to cope with machine suspend/resume ([#13](https://codeberg.org/ivarch/pv/issues/13))
|
||||
* *fix:* if **--width** or **--height** were provided, do not change them when the window size changes ([#36](https://codeberg.org/ivarch/pv/issues/36))
|
||||
* *fix:* when a file descriptor position in **--watchfd** moves backwards, show the rate using the correct prefix ([#41](https://codeberg.org/ivarch/pv/issues/41))
|
||||
* *fix:* rewrite terminal state save/restore so state is not intermittently garbled on exit when using **--cursor** ([#20](https://codeberg.org/ivarch/pv/issues/20)), ([#24](https://codeberg.org/ivarch/pv/issues/24))
|
||||
|
||||
#### Cleanups
|
||||
|
||||
* *cleanup:* addressed many potential issues highlighted by the software auditing tools "`splint`" and "`flawfinder`" (see new target "`make analyse`")
|
||||
* *cleanup:* switched the build system to GNU Automake
|
||||
* *cleanup:* replaced the test harness with the one native to GNU Automake
|
||||
* *cleanup:* added a test for terminal width detection to "`make check`"
|
||||
* *cleanup:* added a test to "`make check`" to ensure that "`make install`" installs everything expected
|
||||
* *cleanup:* replaced *AC_HEADER_TIOCGWINSZ* with *AC_CHECK_HEADERS(sys/ioctl.h)* for better MacOS compatibility ([#74](https://codeberg.org/ivarch/pv/issues/74))
|
||||
* *cleanup:* with **--sync**, call `fsync()` instead of `fdatasync()` on incapable systems ([#73](https://codeberg.org/ivarch/pv/issues/73))
|
||||
* *cleanup:* the manual is now a static file instead of needing to be built with "`configure`"
|
||||
|
||||
#### Dropped items
|
||||
|
||||
* *dropped:* dropped support for **--enable-static-nls**
|
||||
* *dropped:* removed the Linux Software Map file, as the LSM project appears to be long dead
|
||||
* *dropped:* will no longer publish to SourceForge as it has a chequered history and is unnecessary
|
||||
* *dropped:* removed project from GitHub and moved to Codeberg - see "[Give Up GitHub](https://giveupgithub.org/)"
|
||||
|
||||
#### Other items
|
||||
|
||||
* licensing change from Artistic 2.0 to GPLv3+
|
||||
|
||||
### 1.7.24 - 30 July 2023
|
||||
|
||||
* *fix:* correct terminal size detection, broken in 1.7.17 by the configuration script rewrite ([#72](https://codeberg.org/ivarch/pv/issues/72))
|
||||
* *security:* removed *DEBUG* environment variable in debug mode, added **--debug** instead
|
||||
* *cleanup:* added "`make analyse`" to run "`splint`" and "`flawfinder`" on all source files
|
||||
* *cleanup:* corrected detection of boolean capability
|
||||
* *cleanup:* word wrapping of **--help** output is now multi-byte locale aware
|
||||
* *cleanup:* adjusted "`indent`" rules to line length of 120 and reformatted code
|
||||
|
||||
### 1.7.18 - 28 July 2023
|
||||
|
||||
* *fix:* language file installation had been broken by the configuration script rewrite
|
||||
|
||||
### 1.7.17 - 27 July 2023
|
||||
|
||||
* *feature:* new **--sync** option to flush cache to disk after every write (related to [#6](https://codeberg.org/ivarch/pv/issues/6), to improve accuracy when writing to slow disks)
|
||||
* *feature:* new **--direct-io** option to bypass cache - implements [#29 "Option to enable O_DIRECT"](https://codeberg.org/ivarch/pv/issues/29) - requested by Romain Kang, Jacek Wielemborek
|
||||
* *fix:* correct byte prefix size to 2 spaces in rate display, so progress display size remains constant at low transfer rates
|
||||
* *cleanup:* rewrote `configure.in` as per suggestions in newer "`autoconf`" manuals
|
||||
* *cleanup:* replaced `header.in` with one generated by "`autoheader`", moving custom logic to a separate header file "`config-aux.h`"
|
||||
* *cleanup:* added copyright notice to all source files as per GNU standards
|
||||
* *cleanup:* changed **--version** output to conform to GNU standards
|
||||
* *cleanup:* replaced backticks with `$()` in all shell scripts that did not come from elsewhere, as backticks are deprecated and harder to read
|
||||
* *cleanup:* improved the output formatting of "`make test`"
|
||||
* *cleanup:* extended the "`make test`" mechanism to allow certain tests to be skipped on platforms that cannot support them
|
||||
* *cleanup:* skip the "pipe" test (for *SIGPIPE*) if GNU "`head`" is not available, so that "`make test`" on stock OpenBSD 7.3 works
|
||||
* *cleanup:* added a lot more tests to "`make test`"
|
||||
* *cleanup:* replace all calls to `sprintf()` and `snprintf()` with a new wrapper function `pv_snprintf()` to improve security and compatibility
|
||||
* *cleanup:* replace all calls to `strcat()` with a wrapper `pv_strlcat()` to improve security and compatibility
|
||||
* *cleanup:* replace all `write()` calls to the terminal with a wrapper `pv_write_retry()` for consistency
|
||||
* *cleanup:* tidy up and fix compilation warning in **--watchfd** code
|
||||
* *cleanup:* rewrote all local shell scripts to pass analysis by [ShellCheck](https://www.shellcheck.net)
|
||||
|
||||
### 1.7.0 - 17 July 2023
|
||||
|
||||
* *dropped:* support for Red Hat Enterprise Linux and its derivatives has been dropped; removed the RPM spec file, and will no longer build binaries
|
||||
* *feature:* the **--size** option now accepts "`@filename`" to use the size of another file (pull request [#57](https://codeberg.org/ivarch/pv/pulls/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* *feature:* the **--watchfd** option is now available on OS X (pull request [#60](https://codeberg.org/ivarch/pv/pulls/60) supplied by [christoph-zededa](https://github.com/christoph-zededa))
|
||||
* *feature:* new **--bits** option to show bit count instead of byte count (adapted from pull request [#63](https://codeberg.org/ivarch/pv/pulls/63) supplied by [Nick Black](https://nick-black.com))
|
||||
* *feature:* new **--average-rate-window** option, to set the window over which the average rate is calculated, also used for ETA (modified from pull request [#65](https://codeberg.org/ivarch/pv/pulls/65) supplied by [lemonsqueeze](https://github.com/lemonsqueeze))
|
||||
* *feature:* the **--watchfd** option will now show relative filenames, if they are under the current directory (pull request [#66](https://codeberg.org/ivarch/pv/pulls/66) supplied by [ikasty](https://github.com/ikasty))
|
||||
* *fix:* correction to `pv_in_foreground()` to behave as its comment block says it should, when not on a terminal - corrects [#19 "No output in Arch Linux initcpio after 1.6.6"](https://codeberg.org/ivarch/pv/issues/19), [#31 "No output written from inside zsh <() construct"](https://codeberg.org/ivarch/pv/issues/31), [#55 "pv Stopped Working in the Background"](https://codeberg.org/ivarch/pv/issues/55) (pull request [#64](https://codeberg.org/ivarch/pv/pulls/64) supplied by [Michael Weiß](https://github.com/quitschbo))
|
||||
* *fix:* workaround for OS X 11 behaviour in configure script regarding stat64 at compile time (pull request [#57](https://codeberg.org/ivarch/pv/pulls/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* *fix:* workaround for macOS equivalence of stat to stat64 - patches from [Filippo Valsorda](https://github.com/FiloSottile) and [Demitri Muna](https://github.com/demitri), correcting [#33 "Fix compilation problems due to `stat64()` on Apple Silicon"](https://codeberg.org/ivarch/pv/issues/33)
|
||||
* *fix:* add burst rate limit to transfer, so rate limits are not broken by bursty traffic (pull request [#62](https://codeberg.org/ivarch/pv/pulls/62) supplied by [Volodymyr Bychkovyak](https://github.com/vbychkoviak))
|
||||
* *fix:* corrected **--force** option so it will still output progress when not in the same process group as the owner of the terminal - corrects [#23 "No output with "-f" when run in background after 1.6.6"](https://codeberg.org/ivarch/pv/issues/23) and helps to correct [#31 "No output written from inside zsh <() construct"](https://codeberg.org/ivarch/pv/issues/31)
|
||||
* *fix:* corrected elapsed time display to show as D:HH:MM:SS after 1 day, like the ETA does - corrects [#16 "Show days in same format in ETA as in elapsed time"](https://codeberg.org/ivarch/pv/issues/16)
|
||||
* *fix:* corrected bug where percentages went down after 100% when in **--numeric** mode with a **--size** that was too small - corrects [#26 "Correct "-n" behaviour when going past 100% of "-s" size"](https://codeberg.org/ivarch/pv/issues/26)
|
||||
* *i18n:* recoded Polish translation file to UTF-8
|
||||
* *i18n:* removed inaccurate fuzzy translation matches
|
||||
* *docs:* moved all open issues into GitHub and updated the TODO list
|
||||
* *docs:* renamed README to README.md and altered it to Markdown format
|
||||
* *docs:* moved contributors from the README to docs/ACKNOWLEDGEMENTS.md
|
||||
* *docs:* moved TODO to TODO.md and altered it to Markdown format
|
||||
* *docs:* moved NEWS to NEWS.md, converted it to UTF-8, and altered it to Markdown format
|
||||
|
||||
### 1.6.20 - 12 September 2021
|
||||
|
||||
* *fix:* add missing `stddef.h` include to `number.c` (Sam James)
|
||||
|
||||
### 1.6.19 - 5 September 2021
|
||||
|
||||
* *fix:* starting pv in the background no longer immediately stops unless the transfer is to/from the terminal (Andriy Gapon, Jonathan Elchison)
|
||||
* *fix:* using **-B**, **-A**, or **-T** now switches on **-C** implicitly (Johannes Gerer, André Stapf)
|
||||
* *fix:* AIX build fixes (Peter Korsgaard)
|
||||
* *i18n:* updated German **--help** translations (Richard Fonfara)
|
||||
* *i18n:* switched to UTF-8 encoding, added missing translations (de,fr,pt)
|
||||
* *docs:* new "common switches" manual section (Jacek Wielemborek)
|
||||
* *docs:* use placeholder instead of `/dev/sda` in the manual (Pranav Peshwe)
|
||||
* *docs:* mention MacOS pipes and **-B 1024** in the manual (Jan Venekamp)
|
||||
* *docs:* correct shell in `autoconf/scripts/index.sh` (Juan Picca)
|
||||
* *cleanup:* various compiler warnings cleaned up
|
||||
|
||||
Full changelog is below:
|
||||
|
||||
* (r181) added common switches section to manual (Jacek Wielemborek)
|
||||
* (r184) use placeholder instead of /dev/sda in the manual (Pranav Peshwe)
|
||||
* (r185) replace ash with sh in autoconf/scripts/index.sh (Juan Picca)
|
||||
* (r185) added note to manual about **-B 1024** in MacOS pipes (Jan Venekamp)
|
||||
* (r185) fix AIX config check when the CWD contains "yes" (Peter Korsgaard)
|
||||
* (r189) (#1556) updated German **--help** translations (Richard Fonfara)
|
||||
* (r189) updated missing German translations and changed to UTF-8 encoding
|
||||
* (r191) updated missing French translations and changed to UTF-8 encoding
|
||||
* (r193) updated missing Portuguese translations, changed to UTF-8 encoding
|
||||
* (r196) (#1563) using **-B**, **-A**, or **-T** now switches on **-C** implicitly (Johannes Gerer, André Stapf)
|
||||
* (r199) fixed numerous compiler warnings in newer GCC versions
|
||||
* (r200,205) fixed bug where "`pv /dev/zero >/dev/null &`" stopped immediately (Jonathan Elchison, Andriy Gapon)
|
||||
* (r203,205) marked unused arguments with GCC unused attribute, started using boolean data type for flags, corrected more compiler warnings
|
||||
|
||||
### 1.6.6 - 30 June 2017
|
||||
|
||||
* (r161) use `%llu` instead of `%Lu` for better compatibility (Eric A. Borisch)
|
||||
* (r162) (#1532) fix target buffer size (**-B**) being ignored (AndCycle, Ilya Basin, Antoine Beaupré)
|
||||
* (r164) cap read/write sizes, and check elapsed time during read/write cycles, to avoid display hangs with large buffers or slow media; also remove `select()` call from repeated_write function as it slows the transfer down and the wrapping `alarm()` means it is unnecessary
|
||||
* (r169) (#1477) use alternate form for transfer counter, such that 13GB is shown as 13.0GB so it's the same width as 13.1GB (André Stapf)
|
||||
* (r171) cleanup: units corrections in man page, of the form kb -> KiB
|
||||
* (r175) report error in **-d** if process fd directory is unreadable, or if process disappears before we start the main loop (Jacek Wielemborek)
|
||||
|
||||
### 1.6.0 - 15 March 2015
|
||||
|
||||
* fix lstat64 support when unavailable - separate patches supplied by Ganael Laplanche and Peter Korsgaard
|
||||
* (#1506) new option **-D** / **--delay-start** to only show bar after N seconds (Damon Harper)
|
||||
* new option **--fineta** / **-I** to show ETA as time of day rather than time remaining - patch supplied by Erkki Seppälä (r147)
|
||||
* (#1509) change ETA (**--eta** / **-e**) so that days are given if the hours remaining are 24 or more (Jacek Wielemborek)
|
||||
* (#1499) repeat read and write attempts on partial buffer fill/empty to work around post-signal transfer rate drop reported by Ralf Ramsauer
|
||||
* (#1507) do not try to calculate total size in line mode, due to bug reported by Jacek Wielemborek and Michiel Van Herwegen
|
||||
* cleanup: removed defunct RATS comments and unnecessary copyright notices
|
||||
* clean up displayed lines when using **--watchfd PID**, when PID exits
|
||||
* output errors on a new line to avoid overwriting transfer bar
|
||||
|
||||
### 1.5.7 - 26 August 2014
|
||||
|
||||
* show KiB instead of incorrect kiB (Debian bug #706175)
|
||||
* (#1284) do not gzip man page, for non-Linux OSes (Bob Friesenhahn)
|
||||
* work around "awk" bug in `tests/016-numeric-timer` in decimal "," locales
|
||||
* fix "`make rpm`" and "`make srpm`", extend "`make release`" to sign releases
|
||||
|
||||
### 1.5.3 - 4 May 2014
|
||||
|
||||
* remove *SPLICE_F_NONBLOCK* to fix problem with slow `splice()` (Jan Seda)
|
||||
|
||||
### 1.5.2 - 10 February 2014
|
||||
|
||||
* allow **--watchfd** to look at block devices
|
||||
* let **--watchfd PID:FD** work with **--size N**
|
||||
* moved contributors out of the manual as the list was too long (NB everyone is still listed in the package documentation and always will be)
|
||||
|
||||
### 1.5.1 - 23 January 2014
|
||||
|
||||
* new option **--watchfd** - suggested by Jacek Wielemborek and "fdwatch"
|
||||
* use non-block flag with `splice()`
|
||||
* new display option **--buffer-percent**, suggested by Kim Krecht
|
||||
* new display option **--last-written**, suggested by Kim Krecht
|
||||
* new transfer option **--no-splice**
|
||||
* fix for minor bug which dropped display elements after one empty one
|
||||
* fix for single fd leak on exit (Cristian Ciupitu)
|
||||
|
||||
### 1.4.12 - 5 August 2013
|
||||
|
||||
* new option **--null** - patch supplied by Zing Shishak
|
||||
* AIX build fix (add "`-lc128`") - with help from Pawel Piatek
|
||||
* AIX **-c** fixes - with help from Pawel Piatek
|
||||
* SCO build fix (`po2table.sh`) - reported by Wouter Pronk
|
||||
* test scripts fix for older distributions - patch from Bryan Dongray
|
||||
* fix for `splice()` not using stdin - patch from Zev Weiss
|
||||
|
||||
### 1.4.6 - 22 January 2013
|
||||
|
||||
* added patch from Pawel Piatek to omit *O_NOFOLLOW* in AIX
|
||||
|
||||
### 1.4.5 - 10 January 2013
|
||||
|
||||
* updated manual page to show known problem with **-R** on Cygwin
|
||||
|
||||
### 1.4.4 - 11 December 2012
|
||||
|
||||
* added debugging, see "`pv -h`" when `configure` is run with **--enable-debugging**
|
||||
* rewrote cursor positioning code used when IPC is unavailable (Cygwin)
|
||||
* fixed cursor positioning cursor read answerback problem (Cygwin/Solaris)
|
||||
* fixed bug causing crash when progress displayed with too-small terminal
|
||||
|
||||
### 1.4.0 - 6 December 2012
|
||||
|
||||
* new option **--skip-errors** commissioned by Jim Salter
|
||||
* if stdout is a block device, and we don't know the total size, use the size of that block device as the total (Peter Samuelson)
|
||||
* new option **--stop-at-size** to stop after **--size** bytes
|
||||
* report correct filename on read errors
|
||||
* fix use-after-free bug in remote PID cleanup code
|
||||
* refactored large chunks of code to make it more readable and to replace most static variables with a state structure
|
||||
|
||||
### 1.3.9 - 5 November 2012
|
||||
|
||||
* allow **--format** parameters to be sent with **--remote**
|
||||
* configure option **--disable-ipc**
|
||||
* added tests for **--numeric** with **--timer** and **--bytes**
|
||||
* added tests for **--remote**
|
||||
|
||||
### 1.3.8 - 29 October 2012
|
||||
|
||||
* new **--pidfile** option to save process ID to a file
|
||||
* integrated patch for **--numeric** with **--timer** and **--bytes** (Sami Liedes)
|
||||
* removed signalling from **--remote** to prevent accidental process kills
|
||||
* new **--format** option (originally Vladimir Pal / Vladimir Ermakov)
|
||||
|
||||
### 1.3.4 - 27 June 2012
|
||||
|
||||
* new **--disable-splice** configure script option
|
||||
* fixed line mode size count with multiple files (Moritz Barsnick)
|
||||
* fixes for AIX core dumps (Pawel Piatek)
|
||||
|
||||
### 1.3.1 - 9 June 2012
|
||||
|
||||
* do not use `splice()` if the write buffer is not empty (Thomas Rachel)
|
||||
* added test 15 (pipe transfers), and new test script
|
||||
|
||||
### 1.3.0 - 5 June 2012
|
||||
|
||||
* added Tiger build patch from Olle Jonsson
|
||||
* fix 1024-boundary display garble (Debian bug #586763)
|
||||
* use `splice`(2) where available (Debian bug #601683)
|
||||
* added known bugs section of the manual page
|
||||
* fixed average rate test, 12 (Andrew Macheret)
|
||||
* use IEEE1541 units (Thomas Rachel)
|
||||
* bug with rate limit under 10 fixed (Henry Precheur)
|
||||
* speed up PV line mode (patch: Guillaume Marcais)
|
||||
* remove `LD=ld` from `vars.mk` to fix cross-compilation (paintitgray/PV#1291)
|
||||
|
||||
### 1.2.0 - 14 December 2010
|
||||
|
||||
* integrated improved SI prefixes and **--average-rate** (Henry Gebhardt)
|
||||
* return nonzero if exiting due to *SIGTERM* (Martin Baum)
|
||||
* patch from Phil Rutschman to restore terminal properly on exit
|
||||
* fix i18n especially for **--help** (Sebastian Kayser)
|
||||
* refactored `pv_display`
|
||||
* we now have a coherent, documented, exit status
|
||||
* modified pipe test and new cksum test from Sebastian Kayser
|
||||
* default *CFLAGS* to just "`-O`" for non-GCC (Kjetil Torgrim Homme)
|
||||
* LFS compile fix for OS X 10.4 (Alexandre de Verteuil)
|
||||
* remove *DESTDIR* `/` suffix (Sam Nelson, Daniel Pape)
|
||||
* fixed potential NULL deref in transfer (Elias Pipping / LLVM/Clang)
|
||||
|
||||
### 1.1.4 - 6 March 2008
|
||||
|
||||
* patch from Elias Pipping correcting compilation failure on Darwin 9
|
||||
* patch from Patrick Collison correcting similar problems on OS X
|
||||
* trap *SIGINT* / *SIGHUP* / *SIGTERM* so we clean up IPCs on exit (Laszlo Ersek)
|
||||
* abort if numeric option, eg **-L**, has non-numeric value (Boris Lohner)
|
||||
|
||||
### 1.1.0 - 30 August 2007
|
||||
|
||||
* new option **--remote** (**-R**) to control an already-running process
|
||||
* new option **--line-mode** (**-l**) to count lines instead of bytes
|
||||
* fix for **-L** to be less resource intensive
|
||||
* fix for input/output equivalence check on Mac OS X
|
||||
* fix for size calculation in pipelines on Mac OS X
|
||||
* fixed "`make uninstall`"
|
||||
* removed "`/debian`" directory at request of new Debian maintainer
|
||||
|
||||
### 1.0.1 - 4 August 2007
|
||||
|
||||
* licensing change from Artistic to Artistic 2.0
|
||||
* removed the **-l** / **--license** option
|
||||
|
||||
### 1.0.0 - 2 August 2007
|
||||
|
||||
* act more like "`cat`" - just skip unreadable files, don't abort
|
||||
* removed text version of manual page, and obsolete Info file generation
|
||||
* code cleanup and separation of PV internals from CLI front-end
|
||||
|
||||
### 0.9.9 - 5 February 2007
|
||||
|
||||
* new option **--buffer-size** (**-B**) suggested by Mark Tomich
|
||||
* build fix: HP/UX largefile compile fix from Timo Savinen
|
||||
* maintain better buffer filling during transfers
|
||||
* workaround: "`pv /dev/zero | dd bs=1M count=1k`" bug (reported by Gert Menke)
|
||||
* dropped support for the Texinfo manual
|
||||
|
||||
### 0.9.6 - 27 February 2006
|
||||
|
||||
* bugfix: `key_t` incompatibility with Cygwin
|
||||
* bugfix: interval (**-i**) parameter parses numbers after decimal point
|
||||
* build fix: use static NLS if `msgfmt` is unavailable
|
||||
* on the final update, blank out the now-zero ETA
|
||||
|
||||
### 0.9.2 - 1 September 2005
|
||||
|
||||
* Daniel Roethlisberger patch: use lockfiles if terminal locking fails
|
||||
|
||||
### 0.9.1 - 16 June 2005
|
||||
|
||||
* minor RPM spec file fix for Fedora Core 4
|
||||
|
||||
### 0.9.0 - 15 November 2004
|
||||
|
||||
* minor NLS bugfix
|
||||
|
||||
### 0.8.9 - 6 November 2004
|
||||
|
||||
* decimal values now accepted for rate and size, eg **-L 1.23M**
|
||||
* code cleanup
|
||||
* developers: "`make help`" now lists Makefile targets
|
||||
|
||||
### 0.8.6 - 29 June 2004
|
||||
|
||||
* use `uu_lock()` for terminal locking on FreeBSD
|
||||
|
||||
### 0.8.5 - 2 May 2004
|
||||
|
||||
* cursor positioning (**-c**) reliability improved on systems with IPC
|
||||
* minor fix: made test 005 more reliable
|
||||
* new option **--height** (**-H**)
|
||||
|
||||
### 0.8.2 - 24 April 2004
|
||||
|
||||
* allow k,m,g,t suffixes on numbers
|
||||
* added "`srpm`" and "`release`" Makefile targets
|
||||
|
||||
### 0.8.1 - 19 April 2004
|
||||
|
||||
* bugfix in cursor positioning (**-c**)
|
||||
|
||||
### 0.8.0 - 12 February 2004
|
||||
|
||||
* replaced GNU getopt with my library code
|
||||
* replaced GNU gettext with my very minimal replacement
|
||||
* use *DESTDIR* instead of *RPM_BUILD_ROOT* for optional installation prefix
|
||||
* looked for flaws using RATS, cleaned up code
|
||||
|
||||
### 0.7.0 - 8 February 2004
|
||||
|
||||
* display buffer management fixes (thanks Cédric Delfosse)
|
||||
* replaced **--enable-debug** with **--enable-debugging** and **--enable-profiling**
|
||||
|
||||
### 0.6.4 - 14 January 2004
|
||||
|
||||
* fixed minor bug in RPM installation
|
||||
* bugfix in "`make index`" (only of interest to developers)
|
||||
|
||||
### 0.6.3 - 22 December 2003
|
||||
|
||||
* fixed transient bug that reported "resource unavailable" occasionally
|
||||
|
||||
### 0.6.2 - 6 August 2003
|
||||
|
||||
* block devices now have their size read correctly, so "`pv /dev/hda1`" works
|
||||
* minor code cleanups (mainly removal of CVS "Id" tags)
|
||||
|
||||
### 0.6.0 - 3 August 2003
|
||||
|
||||
* doing *^Z* then "`bg`" then "`fg`" now continues displaying
|
||||
|
||||
### 0.5.9 - 23 July 2003
|
||||
|
||||
* fix for test 007 when not in C locale
|
||||
* fix for build process to use *CPPFLAGS*
|
||||
* fix for build process to use correct i18n libraries
|
||||
* fix for build process - more portable sed in dependency generator
|
||||
* fix for install process - remember to `mkinstalldirs` before installing
|
||||
* fixes for building on Mac OS X
|
||||
|
||||
### 0.5.3 - 4 May 2003
|
||||
|
||||
* added Polish translation thanks to Bartosz Feński <fenio@o2.pl> <http://skawina.eu.org/> and Krystian Zubel
|
||||
* moved `doc/debian` to `./debian` at insistence of common sense
|
||||
* minor Solaris 8 compatibility fixes
|
||||
* seems to compile and test OK on Mac OS X
|
||||
|
||||
### 0.5.0 - 15 April 2003
|
||||
|
||||
* added French translation thanks to Stéphane Lacasse <stephane@gorfou.ca>
|
||||
* added German translation thanks to Marcos Kreinacke <public@kreinacke.com>
|
||||
* switched LGPL reference from "Library" to "Lesser"
|
||||
|
||||
### 0.4.9 - 18 February 2003
|
||||
|
||||
* support for >2GB files added where available (Debian bug #180986)
|
||||
* added `doc/debian` dir (from Cédric Delfosse)
|
||||
* added "`make rpm`" and "`make deb`" targets to build RPM and Debian packages
|
||||
* added a "`make pv-static`" rule to build a statically linked version
|
||||
|
||||
### 0.4.5 - 13 December 2002
|
||||
|
||||
* added Portuguese (Brazilian) translation thanks to Eduardo Aguiar
|
||||
|
||||
### 0.4.4 - 7 December 2002
|
||||
|
||||
* pause/resume support - don't count time while stopped
|
||||
* stop output when resumed in the background
|
||||
* terminal size change support
|
||||
* bugfix: "`<=>`" indicator no longer sticks at right hand edge
|
||||
|
||||
### 0.4.0 - 27 November 2002
|
||||
|
||||
* allow decimal interval values, eg 0.1, 0.5, etc
|
||||
* some simple tests added ("`make check`")
|
||||
* smoother throughput limiting (**--rate-limit**), now done in 0.1sec chunks
|
||||
* bounds-check interval values (**-i**) - max update interval now 10 minutes
|
||||
* more reliable non-blocking output to keep display updated
|
||||
* no longer rely on `atoll()`
|
||||
* don't output final blank line if **--numeric**
|
||||
* use `fcntl()` instead of `flock()` for Solaris compatibility
|
||||
|
||||
### 0.3.0 - 25 November 2002
|
||||
|
||||
* handle broken output pipe gracefully
|
||||
* continue updating display even when output pipe is blocking
|
||||
|
||||
### 0.2.6 - 21 October 2002
|
||||
|
||||
* we now ignore *EINTR* on `select()`
|
||||
* variable-size buffer (still need to add code to change size)
|
||||
* added (tentative) support for internationalisation
|
||||
* removed superfluous **--no-progress**, etc options
|
||||
* optimised transfer by using bigger buffers, based on `st_blksize`
|
||||
* added **--wait** option to wait until transfer begins before showing progress
|
||||
* added **--rate-limit** option to limit rate to a maximum throughput
|
||||
* added **--quiet** option (no output at all) to be used with **--rate-limit**
|
||||
|
||||
### 0.2.5 - 23 July 2002
|
||||
|
||||
* added *[FILE]...* arguments, like "`cat`"
|
||||
* function separation in code
|
||||
* some bug fixes related to numeric overflow
|
||||
|
||||
### 0.2.3 - 19 July 2002
|
||||
|
||||
* Texinfo manual written, man page updated
|
||||
* byte counter added
|
||||
|
||||
### 0.2.0 - 18 July 2002
|
||||
|
||||
* ETA counter added
|
||||
* screen width estimation added
|
||||
* progress bar added
|
||||
|
||||
### 0.1.0 - 17 July 2002
|
||||
|
||||
* main loop created
|
||||
* rate counter added
|
||||
* elapsed time counter added
|
||||
* percentage calculation added
|
||||
|
||||
### 0.0.1 - 16 July 2002
|
||||
|
||||
* package created
|
||||
* first draft of man page written
|
||||
Executable
+701
@@ -0,0 +1,701 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Benchmark transfer rates, and analyse benchmark results.
|
||||
#
|
||||
# Measures transfer rates and CPU usage with various different options,
|
||||
# multiple times, then calculates the mean and standard deviation for each
|
||||
# set of measurements.
|
||||
#
|
||||
# The results are written to stdout as tab-separated values, each line
|
||||
# prefixed with an opaque system ID (based on "uname -a"), the PV version
|
||||
# expressed as an integer, and a run ID based on the start date and time.
|
||||
#
|
||||
# In analysis mode, reads results from multiple benchmark runs on standard
|
||||
# input, and for each type of measurement, show the differences between
|
||||
# either the different PV versions or the different runs.
|
||||
|
||||
# Defaults.
|
||||
pv='pv' # PV executable to run the measurements with
|
||||
rounds='10' # how many rounds of measurements to take
|
||||
testFileMB='256' # max size of each of the test files, in MiB
|
||||
testZeroesMB='1024' # amount of /dev/zero data to use, in MiB
|
||||
sourcesDir='' # directory containing sources to benchmark
|
||||
compareWhat='auto' # what to compare in the analysis
|
||||
finalLineOnly='false' # whether to only show the last measurement's analysis
|
||||
terseFormat='false' # whether to use a terse report format
|
||||
|
||||
# Script information for --help and --version.
|
||||
programName='benchmark-pv-transfers'
|
||||
programVersion='1.0.0'
|
||||
bugReportsTo='https://codeberg.org/ivarch/pv/issues'
|
||||
copyrightYear='2026'
|
||||
copyrightHolder='Andrew Wood'
|
||||
|
||||
# Constants.
|
||||
fieldsPerRecord='4' # measurements taken: rate, time - real, user, sys.
|
||||
|
||||
# Hash function - write hex on stdout based on a hash of stdin.
|
||||
runHash () {
|
||||
command -v md5sum >/dev/null 2>&1 && exec md5sum
|
||||
# OpenBSD has no "md5sum" but does have "cksum -a md5".
|
||||
cksum -r -a md5 2>/dev/null || cksum
|
||||
}
|
||||
|
||||
# Define the measurements. Each measurement definition contains:
|
||||
# - The ID of the measurement
|
||||
# - The name of the measurement
|
||||
# - A space-separated list of single-letter options that PV must support
|
||||
# - How many testFileMB multiples are transferred, or Z for testZeroesMB
|
||||
# - The command to run
|
||||
# In the command to run, {PV} is replaced with the path to PV, {FILE1} and
|
||||
# {FILE2} are replaced by the random data filenames, {ZSIZE} is replaced by
|
||||
# testZeroesMB, and {OUTPUT} is replaced by a temporary output filename.
|
||||
# Each definition is stored as single line, with the above parts separated
|
||||
# by "!".
|
||||
measurementDefinitions=''
|
||||
# Add a definition (name, options list, data size, command) to the
|
||||
# definitions array.
|
||||
addDefinition () {
|
||||
measurementDefinitions="$(
|
||||
printf '%s\n%s!%s!%s!%s!%s\n' \
|
||||
"${measurementDefinitions}" \
|
||||
"$(printf '%s\n' "$1" | runHash | cut -b1-7)" \
|
||||
"$1" "$2" "$3" "$4" \
|
||||
| grep .
|
||||
)"
|
||||
}
|
||||
# Add a set of standard definitions for measurements, naming them with a
|
||||
# prefix "$1: ", each with extra options "$2".
|
||||
addStandardMeasurements () {
|
||||
# From file via stdin to file via stdout.
|
||||
addDefinition "$1: stdin file to file" "$2" 1 "{PV} $2 < {FILE1} > {OUTPUT}"
|
||||
# From file to file via stdout.
|
||||
addDefinition "$1: file to file" "$2" 1 "{PV} $2 {FILE1} > {OUTPUT}"
|
||||
# From two files to file via stdout.
|
||||
addDefinition "$1: two files to file" "$2" 2 "{PV} $2 {FILE1} {FILE2} > {OUTPUT}"
|
||||
# From pipe to file via stdout.
|
||||
addDefinition "$1: pipe to file" "$2" 1 "cat {FILE1} | {PV} $2 > {OUTPUT}"
|
||||
# From file via stdin to pipe.
|
||||
addDefinition "$1: stdin file to pipe" "$2" 1 "{PV} $2 < {FILE1} | cat > {OUTPUT}"
|
||||
# From file to pipe.
|
||||
addDefinition "$1: file to pipe" "$2" 1 "{PV} $2 {FILE1} | cat > {OUTPUT}"
|
||||
# From two files to pipe.
|
||||
addDefinition "$1: two files to pipe" "$2" 2 "{PV} $2 {FILE1} {FILE2} | cat > {OUTPUT}"
|
||||
# From pipe to pipe.
|
||||
addDefinition "$1: pipe to pipe" "$2" 1 "cat {FILE1} | {PV} $2 | cat > {OUTPUT}"
|
||||
}
|
||||
# Generate the measurement definitions, most of which are based on repeated
|
||||
# blocks of the above standard measurements, with various different options.
|
||||
defineMeasurements () {
|
||||
addStandardMeasurements 'Default' ''
|
||||
addStandardMeasurements 'No-splice' '-C'
|
||||
addStandardMeasurements 'Pipe buffer 1M' '-J 1M'
|
||||
addStandardMeasurements 'Transfer buffer 1M' '-B 1M'
|
||||
|
||||
addStandardMeasurements 'Discard' '-X'
|
||||
addStandardMeasurements 'Discard with no-splice' '-X -C'
|
||||
addStandardMeasurements 'Discard with pipe buffer 1M' '-X -J 1M'
|
||||
addStandardMeasurements 'Discard with transfer buffer 1M' '-X -B 1M'
|
||||
|
||||
addDefinition "Zeroes: stdout to /dev/null" '-S -s' Z "{PV} -S -s {ZSIZE}M /dev/zero > /dev/null"
|
||||
addDefinition "Zeroes: stdout to pipe" '-S -s' Z "{PV} -S -s {ZSIZE}M /dev/zero | cat > /dev/null"
|
||||
addDefinition "Zeroes: discarded" '-X -S -s' Z "{PV} -X -S -s {ZSIZE}M /dev/zero"
|
||||
addDefinition "Zeroes: stdout to /dev/null with no-splice" '-C -S -s' Z "{PV} -C -S -s {ZSIZE}M /dev/zero > /dev/null"
|
||||
addDefinition "Zeroes: stdout to pipe with no-splice" '-C -S -s' Z "{PV} -C -S -s {ZSIZE}M /dev/zero | cat > /dev/null"
|
||||
addDefinition "Zeroes: discarded with no-splice" '-C -X -S -s' Z "{PV} -C -X -S -s {ZSIZE}M /dev/zero"
|
||||
}
|
||||
|
||||
# Write an error message $1 to standard error, prefixed with the program
|
||||
# name.
|
||||
error () {
|
||||
printf '%s: %s\n' "${programName}" "$1" >&2
|
||||
}
|
||||
|
||||
# Output an error message $1, and exit with a failure status.
|
||||
die () {
|
||||
error "$1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Show all measurement definitions.
|
||||
showMeasurementDefinitions () {
|
||||
printf '%s\n%s\n' 'ID!Name!Opts!Size!Command' "${measurementDefinitions}" \
|
||||
| awk -F '!' '{printf "%s\t%-60s\t%s\n", $1, $2, $5}'
|
||||
}
|
||||
|
||||
# Sort a list of version numbers on stdin, in version order.
|
||||
versionSort () {
|
||||
# If sort has no -V, like on CentOS 5, fall back to a simplistic
|
||||
# substitute.
|
||||
sort -V 2>/dev/null \
|
||||
|| perl -pe '$x=$_;$x=~s/(0*[0-9]+)/sprintf("%09d",$1)/ge;chomp $x;$_=$x." ".$_' | sort | awk '{print $2}'
|
||||
}
|
||||
|
||||
# Write a line of results for the measurement with ID $1 and name $2, round
|
||||
# ${thisRound}, reading the times from ${workDir}/times and deriving the
|
||||
# rate from the elapsed time (the real time in the times file) and the size
|
||||
# written in ${workDir}/size. Removes those two files in the process.
|
||||
#
|
||||
# The results are also spooled to ${workDir}/results for later analysis,
|
||||
# prefixed with only the ID $1.
|
||||
resultsLine () {
|
||||
testTimeReal="$(awk '$1=="real" {print $2}' "${workDir}/times")"
|
||||
testTimeUser="$(awk '$1=="user" {print $2}' "${workDir}/times")"
|
||||
testTimeSystem="$(awk '$1=="sys" {print $2}' "${workDir}/times")"
|
||||
testRate="$(awk -v t="${testTimeReal}" '{if (t>0) { printf "%.3f\n", $1/t } else { print "-" }}' < "${workDir}/size")"
|
||||
test -n "${testRate}" || testRate='-'
|
||||
rm -f "${workDir}/times" "${workDir}/size"
|
||||
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "${outputPrefix}" "${thisRound}" "$1" "${testRate}" "${testTimeReal}" "${testTimeUser}" "${testTimeSystem}" "$2"
|
||||
printf '%s\t%s\t%s\t%s\t%s\n' "$1" "${testRate}" "${testTimeReal}" "${testTimeUser}" "${testTimeSystem}" >> "${workDir}/results"
|
||||
}
|
||||
|
||||
# Run $2 in a shell under "time", writing $1 to ${workDir}/size and the
|
||||
# times to ${workDir}/times.
|
||||
captureTimes () {
|
||||
printf '%s\n' "$1" > "${workDir}/size"
|
||||
(
|
||||
TIMEFORMAT="real %3R
|
||||
user %3U
|
||||
sys %3S"
|
||||
time sh -c "{ $2; } 2>&3"
|
||||
) 3>&2 2>"${workDir}/times"
|
||||
}
|
||||
|
||||
# Run all defined measurements for which the required options are available.
|
||||
#
|
||||
# If "${workDir}/permitted-measurements" is not empty, only measurements
|
||||
# with IDs listed in that file will be taken.
|
||||
gatherMeasurements () {
|
||||
printf '%s\n' "${measurementDefinitions}" \
|
||||
| {
|
||||
while read -r definitionLine; do
|
||||
measurementId="${definitionLine%%!*}"
|
||||
measurementName="${definitionLine#*!}"
|
||||
measurementName="${measurementName%%!*}"
|
||||
requiredOptions="${definitionLine#*!}"
|
||||
requiredOptions="${requiredOptions#*!}"
|
||||
requiredOptions="${requiredOptions%%!*}"
|
||||
dataSize="${definitionLine#*!}"
|
||||
dataSize="${dataSize#*!}"
|
||||
dataSize="${dataSize#*!}"
|
||||
dataSize="${dataSize%%!*}"
|
||||
templateCommand="${definitionLine##*!}"
|
||||
|
||||
test -n "${templateCommand}" || continue
|
||||
|
||||
if test -s "${workDir}/permitted-measurements"; then
|
||||
grep -Fqx "${measurementId}" "${workDir}/permitted-measurements" || continue
|
||||
fi
|
||||
|
||||
if test -n "${requiredOptions}"; then
|
||||
optionLetters="$(printf 'x%s\n' "${requiredOptions}" | tr -d '!' | sed 's/-/!-/g' | tr '!' '\n' | grep '^-' | cut -b 2)"
|
||||
optionsPresent='true'
|
||||
for pvOption in ${optionLetters}; do
|
||||
grep -Fq " -${pvOption}" "${workDir}/help" || optionsPresent='false'
|
||||
done
|
||||
${optionsPresent} || continue
|
||||
fi
|
||||
|
||||
# Add some display options to make more information visible
|
||||
# on versions that support them.
|
||||
pvExtraOptions=''
|
||||
pvFormatString='%b %t %r %p %e %T'
|
||||
if grep -Fq " -N" "${workDir}/help"; then
|
||||
pvExtraOptions="${pvExtraOptions} -N '${measurementId}'"
|
||||
pvFormatString="%N ${pvFormatString}"
|
||||
fi
|
||||
grep -Fq " -F" "${workDir}/help" && pvExtraOptions="${pvExtraOptions} -F '${pvFormatString}'"
|
||||
|
||||
activeCommand="$(
|
||||
printf '%s\n' "${templateCommand}" | sed \
|
||||
-e "s!{PV}!${pv}${pvExtraOptions}!g" \
|
||||
-e "s!{FILE1}!${workDir}/file1!g" \
|
||||
-e "s!{FILE2}!${workDir}/file2!g" \
|
||||
-e "s!{ZSIZE}!${testZeroesMB}!g" \
|
||||
-e "s!{OUTPUT}!${workDir}/output!g"
|
||||
)"
|
||||
|
||||
if test "${dataSize}" = "Z"; then
|
||||
dataSize="${testZeroesMB}"
|
||||
else
|
||||
dataSize=$((dataSize*testFileMB))
|
||||
fi
|
||||
|
||||
rm -f "${workDir}/output1" "${workDir}/output2"
|
||||
captureTimes "${dataSize}" "${activeCommand}"
|
||||
resultsLine "${measurementId}" "${measurementName}"
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
# Run several rounds of benchmark measurements using $1 as the pv
|
||||
# executable, producing tab-separated data, including a final section
|
||||
# containing the means and standard deviations for each measurement type.
|
||||
#
|
||||
# If $2 is not blank, only run the measurements whose IDs are listed in it.
|
||||
runBenchmarks () {
|
||||
pv="$1"
|
||||
restrictTo="$2"
|
||||
|
||||
# Check there's enough room for the test files, meaning that 2 test
|
||||
# files + 1 output file + 2MB doesn't add up to more than 75% of the
|
||||
# space on the filesystem holding TMPDIR - make the test files
|
||||
# smaller, if not.
|
||||
tmpSpaceMB="$(df -kP "${TMPDIR:-/tmp}" | awk 'FNR==2 {print int($4*3/4096)}')"
|
||||
while test "${testFileMB}" -gt 4; do
|
||||
test "${tmpSpaceMB}" -gt $((2+3*testFileMB)) && break
|
||||
testFileMB=$((testFileMB/2))
|
||||
done
|
||||
|
||||
# Capture the help text so that capabilities can be checked.
|
||||
${pv} -h > "${workDir}/help"
|
||||
|
||||
# Write a list of permitted measurement IDs, one per line. An empty
|
||||
# file means no restriction.
|
||||
# shellcheck disable=SC2020 # silence the warning about "tr" here.
|
||||
printf '%s\n' "${restrictTo}" \
|
||||
| tr ',; \t' '\n\n\n\n' \
|
||||
| sort -u \
|
||||
| grep . \
|
||||
> "${workDir}/permitted-measurements"
|
||||
|
||||
# Define identifiers for the system this is running on, the pv
|
||||
# version being benchmarked, and this specific benchmark run.
|
||||
sysId="$(uname -a | runHash | cut -b1-7)"
|
||||
pvId="$(${pv} --version | awk 'FNR==1{print $2}' | awk -F . '{print 1000000*$1+1000*$2+$3}')"
|
||||
runId="$(date '+%Y%m%d%H%M%S')"
|
||||
outputPrefix="$(printf '%s\t%s\t%s\n' "${sysId}" "${pvId}" "${runId}")"
|
||||
|
||||
# Basic system information, and a header line for the test results.
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'System hostname' "$(uname -n)"
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'System load' "$(uptime | awk '{printf "%.2f\n",$(NF-2)}')"
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'System kernel type' "$(uname -s)"
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'System kernel release' "$(uname -r)"
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'System OS' "$(uname -o)"
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'PV path' "${pv}"
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'PV version' "$(${pv} -V | awk 'FNR==1 {print $2}')"
|
||||
printf '%s\t%s\t%s\n' "${outputPrefix}" 'Test file size (MB)' "${testFileMB}"
|
||||
|
||||
# Generate two files of random data.
|
||||
dd if='/dev/urandom' of="${workDir}/file1" bs=1048576 count="${testFileMB}" 2>/dev/null
|
||||
dd if='/dev/urandom' of="${workDir}/file2" bs=1048576 count="${testFileMB}" 2>/dev/null
|
||||
|
||||
# Run several rounds of measurements.
|
||||
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "${outputPrefix}" '#' 'ID' 'MiB/sec' 'Real time' 'User CPU time' 'System CPU time' 'Raw measurement'
|
||||
thisRound=0
|
||||
while test ${thisRound} -lt "${rounds}"; do
|
||||
thisRound=$((1+thisRound))
|
||||
gatherMeasurements
|
||||
done
|
||||
|
||||
# For each of the types of measurement, report the mean and standard
|
||||
# deviation of each field.
|
||||
awk -F "\t" '{print $1}' < "${workDir}/results" > "${workDir}/measurement-ids"
|
||||
true > "${workDir}/measurement-ids-used"
|
||||
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "${outputPrefix}" 'μ/σ' 'ID' 'MiB/sec' 'Real time' 'User CPU time' 'System CPU time' 'Aggregated measurement'
|
||||
{
|
||||
while read -r measurementId; do
|
||||
# Skip this type of measurement if already processed.
|
||||
grep -Fqx "${measurementId}" "${workDir}/measurement-ids-used" && continue
|
||||
printf '%s\n' "${measurementId}" >> "${workDir}/measurement-ids-used"
|
||||
# Get the associated measurement name.
|
||||
measurementName="$(printf '%s\n' "${measurementDefinitions}" | awk -F '!' -v "x=${measurementId}" '$1==x{print $2}')"
|
||||
# Separate out this measurement type's results.
|
||||
awk -F "\t" -v "mId=${measurementId}" '$1==mId {print}' < "${workDir}/results" \
|
||||
> "${workDir}/measurements"
|
||||
# Calculate the mean of each field.
|
||||
awk -F "\t" -v "mId=${measurementId}" -v "mName=${measurementName}" -v "fieldcount=${fieldsPerRecord}" \
|
||||
'BEGIN { samples=0 }
|
||||
{ samples++; for (field=1; field<=fieldcount; field++) { total[field] += $(1+field) } }
|
||||
END { printf "%s\t%s", "μ", mId; for (field=1; field<=fieldcount; field++) { printf "\t%.3f", total[field]/samples }; printf "\t%s\n", mName }' \
|
||||
< "${workDir}/measurements" > "${workDir}/mean"
|
||||
# Calculate the standard deviation of each field.
|
||||
cat "${workDir}/mean" "${workDir}/measurements" \
|
||||
| awk -F "\t" -v "mId=${measurementId}" -v "mName=${measurementName}" -v "fieldcount=${fieldsPerRecord}" \
|
||||
'BEGIN { samples=0 }
|
||||
FNR==1 { for (field=1; field<=fieldcount; field++) { mean[field] += $(2+field) } }
|
||||
FNR>1 { samples++; for (field=1; field<=fieldcount; field++) { variance=$(1+field)-mean[field]; sum_variance_squared[field] += (variance*variance) } }
|
||||
END { printf "%s\t%s", "σ", mId; for (field=1; field<=fieldcount; field++) { printf "\t%.3f", sqrt(sum_variance_squared[field]/samples) }; printf "\t%s\n", mName }' \
|
||||
> "${workDir}/stddev"
|
||||
sed "s,^,${outputPrefix}!," "${workDir}/mean" "${workDir}/stddev" | tr '!' '\t'
|
||||
done
|
||||
} < "${workDir}/measurement-ids"
|
||||
rm -f "${workDir}/file1" "${workDir}/file2" "${workDir}/output1" "${workDir}/output2"
|
||||
}
|
||||
|
||||
# Reformat data on stdin so that each (whitespace-separated) column is
|
||||
# space-padded and right-aligned to a consistent width for all rows.
|
||||
#
|
||||
# Note that this can only handle ASCII, not UTF-8.
|
||||
lineUpColumns () {
|
||||
tee "${workDir}/lineup-temp" \
|
||||
| awk 'BEGIN {cols=0}
|
||||
/./ {
|
||||
if (NF > cols)
|
||||
cols=NF
|
||||
for (col=1; col<=NF; col++) {
|
||||
if (length($col) >= max[col])
|
||||
max[col]=length($col)
|
||||
}
|
||||
}
|
||||
END {
|
||||
for (col=1; col<=cols; col++) {
|
||||
printf "%d ", max[col]
|
||||
}
|
||||
printf "\n"
|
||||
}
|
||||
' > "${workDir}/lineup-colwidths"
|
||||
cat "${workDir}/lineup-colwidths" "${workDir}/lineup-temp" \
|
||||
| awk '
|
||||
FNR==1 { cols=NF; for (col=1; col<=NF; col++) { max[col]=$col } }
|
||||
FNR>1 {
|
||||
for (col=1; col<=cols; col++) {
|
||||
if (col>1)
|
||||
printf " "
|
||||
val=(col<=NF ? $col : "")
|
||||
printf "%" max[col] "s", val
|
||||
}
|
||||
printf "\n"
|
||||
}'
|
||||
}
|
||||
|
||||
# Read a stream of benchmark data on stdin containing runs from a single
|
||||
# system, and report how the measurements changed across $1 - either "runs"
|
||||
# for benchmark runs, or "versions" for PV versions.
|
||||
compareResults () {
|
||||
comparisonSelector="$1"
|
||||
cat > "${workDir}/raw-system-data"
|
||||
# List the measurement IDs in the order they appear in the data.
|
||||
awk -F "\t" '$4=="σ"{print $5}' < "${workDir}/raw-system-data" > "${workDir}/measurement-ids"
|
||||
case "${comparisonSelector}" in
|
||||
'versions')
|
||||
# List all PV versions for which any data is available.
|
||||
awk -F "\t" '$4=="PV version"{print $2,$5}' "${workDir}/raw-system-data" | sort -nu > "${workDir}/comparison-items"
|
||||
itemHeading='Version'
|
||||
itemField=2
|
||||
;;
|
||||
'runs')
|
||||
# List all runs.
|
||||
awk -F "\t" '$4=="σ"{print $3,$3}' "${workDir}/raw-system-data" | sort -nu > "${workDir}/comparison-items"
|
||||
itemHeading='Run'
|
||||
itemField=3
|
||||
;;
|
||||
esac
|
||||
# Report on each measurement type in turn.
|
||||
true > "${workDir}/measurement-ids-seen"
|
||||
{
|
||||
measurementsCounter=0
|
||||
while read -r measurementId; do
|
||||
# Skip if this measurement was already processed.
|
||||
grep -Fqx "${measurementId}" "${workDir}/measurement-ids-seen" && continue
|
||||
printf '%s\n' "${measurementId}" >> "${workDir}/measurement-ids-seen"
|
||||
# Collect this measurement's mean and standard deviation
|
||||
# records for each distinct item (version or run). If
|
||||
# there's more than one for a single item, average them.
|
||||
{
|
||||
while read -r itemId itemName; do
|
||||
awk -F "\t" \
|
||||
-v "itemField=${itemField}" -v "itemId=${itemId}" -v "itemName=${itemName}" \
|
||||
-v "mId=${measurementId}" \
|
||||
-v "fieldcount=${fieldsPerRecord}" \
|
||||
'BEGIN {samples=0}
|
||||
$itemField==itemId && $5==mId && $4=="μ" { samples++; for (field=1; field<=fieldcount; field++) { mean[field] += $(5+field) } }
|
||||
$itemField==itemId && $5==mId && $4=="σ" { for (field=1; field<=fieldcount; field++) { stddev[field] += $(5+field) } }
|
||||
END {
|
||||
if (samples > 0) {
|
||||
printf "%s", itemName
|
||||
for (field=1; field<=fieldcount; field++) {
|
||||
printf "\t%.3f\t%.3f", mean[field]/samples, stddev[field]/samples
|
||||
}
|
||||
printf "\n"
|
||||
}
|
||||
}' \
|
||||
< "${workDir}/raw-system-data"
|
||||
done
|
||||
} < "${workDir}/comparison-items" > "${workDir}/measurements-per-item"
|
||||
# If there are not at least 2 items for which this
|
||||
# measurement was available, report nothing as no comparison
|
||||
# can be made.
|
||||
test "$(grep -c . "${workDir}/measurements-per-item")" -lt 2 && continue
|
||||
# Show the measurement name and associated command.
|
||||
# Take the measurement name from the input data.
|
||||
measurementName="$(awk -F "\t" -v "mId=${measurementId}" '$4=="σ" && $5==mId {print $NF;exit}' "${workDir}/raw-system-data")"
|
||||
if ! ${terseFormat}; then
|
||||
# Take the command from the definitions.
|
||||
templateCommand="$(printf '%s\n' "${measurementDefinitions}" | awk -F '!' -v "mId=${measurementId}" '$1==mId {print $5}')"
|
||||
printf '\n%s\n' "${measurementName}"
|
||||
test -n "${templateCommand}" && printf ' (%s)\n' "${templateCommand}"
|
||||
fi
|
||||
# Report each item's measurements and how they compare to
|
||||
# the previous item.
|
||||
awk -F "\t" -v "fieldcount=${fieldsPerRecord}" \
|
||||
'{
|
||||
printf "%s", $1
|
||||
for (field=0; field<fieldcount; field++) {
|
||||
if (field > 0) {
|
||||
printf "\t%s", "-";
|
||||
}
|
||||
mean=$(2+2*field)
|
||||
stddev=$(3+2*field)
|
||||
changescore=0
|
||||
printf "\t%.3f\t%.3f", mean, stddev;
|
||||
if (FNR>1) {
|
||||
low=mean-stddev;
|
||||
high=mean+stddev;
|
||||
range=high-low;
|
||||
prevlow=pmean[field]-pstddev[field];
|
||||
prevhigh=pmean[field]+pstddev[field];
|
||||
prevrange=prevhigh-prevlow;
|
||||
if (prevrange < 1)
|
||||
prevrange = 1;
|
||||
if (high > prevhigh) {
|
||||
changescore = (high - prevhigh) / prevrange;
|
||||
} else if (low < prevlow) {
|
||||
changescore = 0 - ((prevlow - low) / prevrange);
|
||||
}
|
||||
}
|
||||
if (changescore < 0.01 && changescore > -0.01) {
|
||||
printf "\t%d", 0
|
||||
} else {
|
||||
printf "\t%s%.2f", (changescore > 0.00 ? "+" : ""), changescore
|
||||
}
|
||||
pmean[field]=mean;
|
||||
pstddev[field]=stddev;
|
||||
}
|
||||
printf "\n"
|
||||
}' \
|
||||
< "${workDir}/measurements-per-item" \
|
||||
> "${workDir}/item-report"
|
||||
# Leave only the last line if finalLineOnly is set.
|
||||
${finalLineOnly} && sed -i -n '$p' "${workDir}/item-report"
|
||||
# In terse mode, prefix each line with the measurement name,
|
||||
# having replaced spaces in it with underscores.
|
||||
if ${terseFormat}; then
|
||||
showName="$(printf '%s\n' "${measurementName}" | tr ' ' '_')"
|
||||
sed "s,^,${showName}!," < "${workDir}/item-report" | tr '!' '\t' > "${workDir}/item-report.prefixed"
|
||||
mv -f "${workDir}/item-report.prefixed" "${workDir}/item-report"
|
||||
fi
|
||||
# Format the report.
|
||||
# Since the column widths are set by an awk script which
|
||||
# doesn't support UTF-8, ASCII headings are used initially,
|
||||
# and adjusted after formatting.
|
||||
measurementsCounter=$((1+measurementsCounter))
|
||||
{
|
||||
# In terse mode, only print one header per system.
|
||||
if test ${measurementsCounter} -eq 1 || ! ${terseFormat}; then
|
||||
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
|
||||
"${itemHeading}" \
|
||||
'M:Rate' 'S:Rate' 'C:Rate' \
|
||||
'-' \
|
||||
'M:tReal' 'S:tReal' 'C:tReal' \
|
||||
'-' \
|
||||
'M:tUser' 'S:tUser' 'C:tUser' \
|
||||
'-' \
|
||||
'M:tSys' 'S:tSys' 'C:tSys' \
|
||||
| {
|
||||
if ${terseFormat}; then
|
||||
sed 's,^,Measurement!,' | tr '!' '\t'
|
||||
else
|
||||
cat
|
||||
fi
|
||||
}
|
||||
fi
|
||||
cat "${workDir}/item-report"
|
||||
} \
|
||||
> "${workDir}/item-report-with-heading"
|
||||
if ${terseFormat}; then
|
||||
cat "${workDir}/item-report-with-heading"
|
||||
else
|
||||
lineUpColumns < "${workDir}/item-report-with-heading" \
|
||||
| sed '1{s,M:,μ:,g;s,S:,σ:,g;s,C:,±:,g;}'
|
||||
fi
|
||||
done
|
||||
} < "${workDir}/measurement-ids" \
|
||||
> "${workDir}/measurements-report"
|
||||
if "${terseFormat}"; then
|
||||
lineUpColumns < "${workDir}/measurements-report" \
|
||||
| sed '1{s,M:,μ:,g;s,S:,σ:,g;s,C:,±:,g;}'
|
||||
else
|
||||
cat "${workDir}/measurements-report"
|
||||
fi
|
||||
}
|
||||
|
||||
# Read a stream of benchmark data from stdin containing one or more runs
|
||||
# from one or more systems, and for each individual system, report how the
|
||||
# measurements changed across either the different PV versions or between
|
||||
# runs, depending on whether $1 is "versions" or "runs".
|
||||
#
|
||||
# If $1 is "auto", then it will be "versions" if data for more than one PV
|
||||
# version is present, otherwise it will be "runs".
|
||||
runAnalysis () {
|
||||
analysisSelector="$1"
|
||||
cat > "${workDir}/raw-data"
|
||||
# Auto-detect what to analyse.
|
||||
if test "${analysisSelector}" = 'auto'; then
|
||||
if test "$(awk -F "\t" '$4=="σ"{print $2}' < "${workDir}/raw-data" | sort -u | grep -c .)" -gt 1; then
|
||||
analysisSelector='versions'
|
||||
else
|
||||
analysisSelector='runs'
|
||||
fi
|
||||
fi
|
||||
# List the system IDs in the order they appear in the data.
|
||||
awk -F "\t" '{print $1}' < "${workDir}/raw-data" | uniq > "${workDir}/sysids"
|
||||
# Report on each system in turn.
|
||||
true > "${workDir}/sysids-seen"
|
||||
{
|
||||
while read -r sysId; do
|
||||
# Skip if this system was already processed.
|
||||
grep -Fqx "${sysId}" "${workDir}/sysids-seen" && continue
|
||||
printf '%s\n' "${sysId}" >> "${workDir}/sysids-seen"
|
||||
# Extract the data for just this system.
|
||||
awk -F "\t" -v "s=${sysId}" '$1==s {print}' < "${workDir}/raw-data" > "${workDir}/system-data"
|
||||
# Report preamble.
|
||||
printf '%79s\n' '' | tr ' ' '-'
|
||||
printf '%s: %s - %s - %s %s\n' \
|
||||
'System' \
|
||||
"$(awk -F "\t" '$4=="System hostname"{print $5;exit}' "${workDir}/system-data")" \
|
||||
"$(awk -F "\t" '$4=="System OS"{print $5;exit}' "${workDir}/system-data")" \
|
||||
"$(awk -F "\t" '$4=="System kernel type"{print $5;exit}' "${workDir}/system-data")" \
|
||||
"$(awk -F "\t" '$4=="System kernel release"{print $5;exit}' "${workDir}/system-data")"
|
||||
${terseFormat} || cat <<EOF
|
||||
|
||||
For each measurement type, each of its aggregate benchmark results are
|
||||
shown. Each field's mean and standard deviation are displayed along with a
|
||||
change indicator showing how different this line's value is from the
|
||||
previous line.
|
||||
EOF
|
||||
compareResults "${analysisSelector}" < "${workDir}/system-data"
|
||||
done
|
||||
} < "${workDir}/sysids"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# Main entry point.
|
||||
|
||||
# Process any command-line options.
|
||||
action='benchmark'
|
||||
restrictMeasurementIdList=''
|
||||
while test -n "$1"; do
|
||||
arg="$1"
|
||||
shift
|
||||
case "${arg}" in
|
||||
'measurements'|'benchmark'|'analyse') action="${arg}" ;;
|
||||
'-h'|'--help')
|
||||
cat - <<EOF
|
||||
Usage: ${programName} [OPTIONS] [ACTION]
|
||||
Benchmark pv transfers - take measurements of transfer rate and CPU usage
|
||||
when calling pv in various different ways, and analyse results from multiple
|
||||
benchmark runs to show how each measurement changes between runs or versions.
|
||||
|
||||
Actions:
|
||||
benchmark - take several rounds of measurements (default action)
|
||||
analyse - analyse benchmark data on stdin from multiple runs
|
||||
measurements - list all benchmark measurement definitions
|
||||
|
||||
Benchmark options:
|
||||
-p, --program FILE benchmark using FILE as the pv executable (${pv})
|
||||
-r, --rounds ROUNDS run ROUNDS sets of measurements (${rounds})
|
||||
-m, --measurement ID only run this specific measurement
|
||||
-s, --size SIZE attempt to use a test file of SIZE MiB (${testFileMB})
|
||||
-z, --zeroes SIZE stop at SIZE MiB for /dev/zero measurements (${testZeroesMB})
|
||||
-d, --dir DIR compile and benchmark each of the tar.gz files in DIR
|
||||
|
||||
Analysis options:
|
||||
-c, --compare WHAT analyse differences in runs, versions, or auto (${compareWhat})
|
||||
-f, --final show only the final item's line in each measurement analysis
|
||||
-t, --terse produce a terser report
|
||||
|
||||
Other options:
|
||||
-h, --help show this help
|
||||
-V, --version show script version
|
||||
|
||||
Default values are shown in brackets.
|
||||
|
||||
Please report any bugs to: ${bugReportsTo}
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
'-V'|'--version')
|
||||
cat - <<EOF
|
||||
${programName} (pv) ${programVersion}
|
||||
Copyright ${copyrightYear} ${copyrightHolder}
|
||||
License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
'-p'|'--program'|'--pv') pv="$1"; test $# -gt 0 && shift ;;
|
||||
'--program='*|'--pv='*) pv="${arg#*=}" ;;
|
||||
'-r'|'--rounds') rounds="$1"; test $# -gt 0 && shift ;;
|
||||
'--rounds='*) rounds="${arg#*=}" ;;
|
||||
'-m'|'--measurement') restrictMeasurementIdList="${restrictMeasurementIdList} $1"; test $# -gt 0 && shift ;;
|
||||
'--measurement='*) restrictMeasurementIdList="${restrictMeasurementIdList} ${arg#*=}" ;;
|
||||
'-s'|'--size') testFileMB="$1"; test $# -gt 0 && shift ;;
|
||||
'--size='*) testFileMB="${arg#*=}" ;;
|
||||
'-z'|'--zeroes') testZeroesMB="$1"; test $# -gt 0 && shift ;;
|
||||
'--zeroes='*) testZeroesMB="${arg#*=}" ;;
|
||||
'-d'|'--dir') sourcesDir="$1"; test $# -gt 0 && shift ;;
|
||||
'--dir='*) sourcesDir="${arg#*=}" ;;
|
||||
'-c'|'--compare') compareWhat="$1"; test $# -gt 0 && shift ;;
|
||||
'--compare='*) compareWhat="${arg#*=}" ;;
|
||||
'-f'|'--final') finalLineOnly='true' ;;
|
||||
'-t'|'--terse') terseFormat='true' ;;
|
||||
'-'*) die "${arg}: unknown option - try \`--help'" ;;
|
||||
*) die "${arg}: unexpected argument - try \`--help'" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check validity of compareWhat, and normalise it.
|
||||
case "${compareWhat}" in
|
||||
'runs'|'run') compareWhat='runs' ;;
|
||||
'versions'|'version') compareWhat='versions' ;;
|
||||
'auto') ;;
|
||||
*) die "--compare: ${compareWhat}: invalid value" ;;
|
||||
esac
|
||||
|
||||
# Use /dev/shm for workspace if possible, to eliminate disk I/O as a factor.
|
||||
if test -z "${TMPDIR}" && test -d '/dev/shm' && mountpoint -q '/dev/shm'; then
|
||||
TMPDIR='/dev/shm'
|
||||
export TMPDIR
|
||||
fi
|
||||
|
||||
# Temporary working area, cleaned up on exit.
|
||||
workDir="$(mktemp -d)" || exit 1
|
||||
trap 'rm -rf "${workDir}"' EXIT
|
||||
|
||||
# Set everything to the "C" locale.
|
||||
LANG=C
|
||||
LC_ALL=C
|
||||
export LANG LC_ALL
|
||||
|
||||
# Define the measurements.
|
||||
defineMeasurements
|
||||
|
||||
# Run the selected action.
|
||||
case "${action}" in
|
||||
'measurements') showMeasurementDefinitions ;;
|
||||
'benchmark')
|
||||
if test -z "${sourcesDir}"; then
|
||||
runBenchmarks "${pv}" "${restrictMeasurementIdList}"
|
||||
else
|
||||
find "${sourcesDir}" -type f -name "*.tar.gz" \
|
||||
| versionSort \
|
||||
| while read -r sourcesFile; do
|
||||
buildDir="$(mktemp -d "${sourcesFile}.build.XXXXXX")" || continue
|
||||
trap 'rm -rf "${workDir}" "${buildDir}"' EXIT
|
||||
tar xzf "${sourcesFile}" -C "${buildDir}" \
|
||||
&& (
|
||||
cd "${buildDir}"/* \
|
||||
&& sh ./configure 1>&2 \
|
||||
&& make 1>&2 \
|
||||
&& mv pv ..
|
||||
) \
|
||||
&& runBenchmarks "${buildDir}/pv" "${restrictMeasurementIdList}"
|
||||
rm -rf "${buildDir}"
|
||||
trap 'rm -rf "${workDir}"' EXIT
|
||||
done
|
||||
fi
|
||||
;;
|
||||
'analyse') runAnalysis "${compareWhat}" ;;
|
||||
esac
|
||||
@@ -18,7 +18,7 @@ dd if=/dev/zero of="${test_input}" bs=1k count=1k >/dev/null 2>&1
|
||||
echo -e "Buf(k)\tRate(k)\tReads\tRsize\tWrites\tWsize"
|
||||
|
||||
for ((buffer=100; buffer<=1000; buffer+=100)); do
|
||||
for ((rate=0; rate<=1000; rate+=100)); do
|
||||
for ((rate=100; rate<=1000; rate+=100)); do
|
||||
rateparm="-L ${rate}k"
|
||||
test ${rate} -eq 0 && rateparm=""
|
||||
strace -tt -o "${strace_output}" \
|
||||
@@ -35,5 +35,3 @@ for ((buffer=100; buffer<=1000; buffer+=100)); do
|
||||
echo -e "${buffer}\t${rate}\t${rdata}\t${wdata}"
|
||||
done
|
||||
done
|
||||
|
||||
# EOF
|
||||
@@ -0,0 +1,958 @@
|
||||
.TH PV 1 2026-08-01 pv-1.11.0 "User Commands"
|
||||
.\"
|
||||
.SH NAME
|
||||
pv \- monitor and manage the progress of data through a pipe
|
||||
.\"
|
||||
.SH SYNOPSIS
|
||||
.B pv
|
||||
[\fIOPTION\fR]... [\fIFILE\fR]...
|
||||
.PP
|
||||
\fBpv\fR [\fIOPTION\fR]... \fB\-d\fR|\fB\-\-watchfd\fR
|
||||
\fIPID\fR[:\fIFD\fR]|=\fINAME\fR|@\fILISTFILE\fR...
|
||||
.PP
|
||||
\fBpv\fR \fB\-R\fR|\fB\-\-remote\fR \fIPID\fR [\fIOPTION\fR]...
|
||||
.PP
|
||||
\fBpv\fR \fB\-Q\fR|\fB\-\-query\fR \fIPID\fR [\fIOPTION\fR]...
|
||||
.PP
|
||||
\fBpv\fR [\fIOPTION\fR]... \fB\-M\fR|\fB\-\-monitor\fR \fISIDE\fR \-\- \fICOMMAND\fR [\fIARGS\fR]...
|
||||
.\"
|
||||
.SH DESCRIPTION
|
||||
Show the progress of data through a pipeline by giving information such as
|
||||
time elapsed, percentage completed (with progress bar), current throughput
|
||||
rate, total data transferred, and ETA.
|
||||
The data flow rate, error handling strategy, buffer size, and cache
|
||||
interaction can all be adjusted.
|
||||
.PP
|
||||
Each \fIFILE\fR is copied to standard output.
|
||||
With no \fIFILE\fR, or when \fIFILE\fR is \*(lq-\*(rq, standard input is
|
||||
read.
|
||||
.PP
|
||||
In \*(lq\fB\-\-watchfd\fR\*(rq mode, inspect another process and show its
|
||||
progress through the files it has open.
|
||||
.PP
|
||||
In \*(lq\fB\-\-monitor\fR\*(rq mode, run a command and display the progress
|
||||
of data through both its standard input and its standard output.
|
||||
.\"
|
||||
.SH OPTIONS
|
||||
.\"
|
||||
.SS "Display switches"
|
||||
If no display switches are specified, \fBpv\fR behaves as if
|
||||
\*(lq\fB\-\-progress\fR\*(rq, \*(lq\fB\-\-timer\fR\*(rq,
|
||||
\*(lq\fB\-\-eta\fR\*(rq, \*(lq\fB\-\-rate\fR\*(rq, and
|
||||
\*(lq\fB\-\-bytes\fR\*(rq had been given.
|
||||
Otherwise, only those display types that are explicitly switched on will be
|
||||
shown.
|
||||
.TP
|
||||
.B \-p, \-\-progress
|
||||
Turn the progress bar on.
|
||||
If any inputs are not files, or are unreadable, and no size was explicitly
|
||||
given with \*(lq\fB\-\-size\fR\*(rq, the progress bar cannot indicate how
|
||||
close to completion the transfer is, so it will just move left and right to
|
||||
indicate that data is moving - or, with \*(lq\fB\-\-gauge\fR\*(rq, the bar
|
||||
will indicate the current rate as a percentage of the maximum rate seen so
|
||||
far.
|
||||
.TP
|
||||
.B \-t, \-\-timer
|
||||
Turn the timer on.
|
||||
This will display the total elapsed time that \fBpv\fR has been running for.
|
||||
.TP
|
||||
.B \-e, \-\-eta
|
||||
Turn the ETA countdown on.
|
||||
This will estimate, based on current transfer rates and the total data size,
|
||||
how long it will be before completion.
|
||||
The countdown is prefixed with \*(lqETA\*(rq.
|
||||
This option will have no effect if the total data size cannot be determined.
|
||||
.TP
|
||||
.B \-I, \-\-fineta
|
||||
Turn the ETA countdown on, but display the estimated local time at which the
|
||||
transfer will finish, instead of the amount of time remaining.
|
||||
When the estimated time is more than 6 hours in the future, the date is
|
||||
shown as well.
|
||||
The time is prefixed with \*(lqFIN\*(rq for finish time.
|
||||
As with \*(lq\fB\-\-eta\fR\*(rq, this option will have no effect if the
|
||||
total data size cannot be determined.
|
||||
.TP
|
||||
.B \-r, \-\-rate
|
||||
Turn the rate counter on.
|
||||
This will display the current rate of data transfer.
|
||||
The rate is shown in square brackets \*(lq[]\*(rq.
|
||||
.TP
|
||||
.B \-a, \-\-average\-rate
|
||||
Turn the average rate counter on.
|
||||
This will display the current average rate of data transfer, over the last
|
||||
30 seconds by default (see \*(lq\fB\-\-average-rate-window\fR\*(rq).
|
||||
The average rate is shown in brackets \*(lq()\*(rq.
|
||||
.TP
|
||||
.B \-b, \-\-bytes
|
||||
Turn the total byte counter on.
|
||||
This will display the total amount of data transferred so far.
|
||||
.TP
|
||||
.B \-T, \-\-buffer\-percent
|
||||
Turn on the transfer buffer percentage display.
|
||||
This will show the percentage of the transfer buffer in use.
|
||||
Implies \*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
The transfer buffer percentage is shown in curly brackets \*(lq{}\*(rq.
|
||||
.TP
|
||||
.BI \-A\ NUM \fR,\ \fB\-\-last\-written\ NUM
|
||||
Show the last \fINUM\fR bytes written.
|
||||
Implies \*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
.TP
|
||||
.BI \-F\ FORMAT \fR,\ \fB\-\-format\ FORMAT
|
||||
Ignore all of the above options and instead use the format string
|
||||
\fIFORMAT\fR to determine the output format.
|
||||
See the \fBFORMATTING\fR section below.
|
||||
.TP
|
||||
.B \-n, \-\-numeric
|
||||
Numeric output.
|
||||
Instead of giving a visual indication of progress, write an integer
|
||||
percentage, one per line, on standard error, suitable for passing to a tool
|
||||
such as \fBdialog\fR(1).
|
||||
Note that \*(lq\fB\-\-force\fR\*(rq is not required if
|
||||
\*(lq\fB\-\-numeric\fR\*(rq is being used.
|
||||
.IP
|
||||
Combining \*(lq\fB\-\-numeric\fR\*(rq with \*(lq\fB\-\-bytes\fR\*(rq will
|
||||
cause the number of bytes processed so far to be output instead of a
|
||||
percentage.
|
||||
Adding \*(lq\fB\-\-line\-mode\fR\*(rq as well as \*(lq\fB\-\-bytes\fR\*(rq
|
||||
writes the number of lines instead of bytes or a percentage.
|
||||
Adding \*(lq\fB\-\-rate\fR\*(rq adds the transfer rate to each output line
|
||||
(if \*(lq\fB\-\-bytes\fR\*(rq is also in use, the rate comes after the
|
||||
byte/line count).
|
||||
Adding \*(lq\fB\-\-timer\fR\*(rq prefixes each output line with the elapsed
|
||||
time so far, as a decimal number of seconds.
|
||||
.IP
|
||||
Combining \*(lq\fB\-\-numeric\fR\*(rq with \*(lq\fB\-\-format\fR\*(rq allows
|
||||
for custom output. The default format string components for
|
||||
\*(lq\fB\-\-numeric\fR\*(rq are
|
||||
\*(lq\fB%t\~%b\~%r\~%{progress\-amount\-only}\fR\*(rq in that order, each
|
||||
item being active or inactive according to the rules above (so the default
|
||||
with no other options is \*(lq\fB%{progress\-amount\-only}\fR\*(rq).
|
||||
.TP
|
||||
.B \-q, \-\-quiet
|
||||
No output.
|
||||
Useful if the \*(lq\fB\-\-rate\-limit\fR\*(rq option is being used on its
|
||||
own to limit the transfer rate of a pipe.
|
||||
.\"
|
||||
.SS "Output modifiers"
|
||||
.TP
|
||||
.B \-8, \-\-bits
|
||||
Use bits instead of bytes for the byte and rate counters.
|
||||
The output suffix will be \*(lqb\*(rq instead of \*(lqB\*(rq.
|
||||
.TP
|
||||
.B \-k, \-\-si
|
||||
Display and interpret suffixes as multiples of 1000 rather than the default
|
||||
of 1024.
|
||||
Note that this only takes effect on options after this one, so for
|
||||
consistency, specify this option first.
|
||||
.TP
|
||||
.B \-W, \-\-wait
|
||||
Wait until the first byte has been transferred before showing any progress
|
||||
information or calculating any ETAs.
|
||||
For example, use this option when piping data into tools such as
|
||||
\fBgpg\fR(1) or \*(lq\fBmysql\~\-p\fR\*(rq so the count only starts after
|
||||
the password prompt has been answered.
|
||||
.TP
|
||||
.BI \-D\ SEC \fR,\ \fB\-\-delay\-start\ SEC
|
||||
Wait until \fISEC\fR seconds have passed before showing any progress
|
||||
information, so that a transfer that is over quickly won't display anything.
|
||||
The value of \fISEC\fR can be a decimal such as \*(lq0.5\*(rq.
|
||||
.TP
|
||||
.BI \-s\ SIZE \fR,\ \fB\-\-size\ SIZE
|
||||
Assume the total amount of data to be transferred is \fISIZE\fR bytes when
|
||||
calculating percentages and ETAs.
|
||||
A suffix of \*(lqK\*(rq, \*(lqM\*(rq, \*(lqG\*(rq, or \*(lqT\*(rq can be
|
||||
added to denote kibibytes (*1024), mebibytes, gibibytes, tebibytes.
|
||||
If \*(lq\fB\-\-si\fR\*(rq appears before this option, suffixes will denote
|
||||
kilobytes (*1000), megabytes, and so on instead.
|
||||
.IP
|
||||
If \fISIZE\fR starts with \*(lq\fB@\fR\*(rq, the size of file whose name
|
||||
follows the @ will be used; if that is a directory, the size of all files
|
||||
under it will be used, like \*(lq\fBdu\~\-\-apparent\-size\~\-b\fR\*(rq.
|
||||
.TP
|
||||
.B \-g, \-\-gauge
|
||||
If the progress bar is shown but the size is not known, then instead of
|
||||
moving the bar left and right to show progress, show the current transfer
|
||||
rate as a percentage of the maximum rate seen so far.
|
||||
.TP
|
||||
.B \-l, \-\-line\-mode
|
||||
Instead of counting bytes, count lines (newline characters).
|
||||
The progress bar will only move when a new line is found, and the value
|
||||
passed to \*(lq\fB\-\-size\fR\*(rq will be interpreted as a line count.
|
||||
.IP
|
||||
If this option is used without \*(lq\fB\-\-size\fR\*(rq, the "total size"
|
||||
(in this case, total line count) is calculated by reading through all input
|
||||
files once before transfer starts.
|
||||
If any inputs are pipes or non-regular files, or are unreadable, the total
|
||||
size will not be calculated.
|
||||
.TP
|
||||
.B \-0, \-\-null
|
||||
Count lines as terminated with a null byte instead of with a newline.
|
||||
This option implies \*(lq\fB\-\-line\-mode\fR\*(rq.
|
||||
.TP
|
||||
.BI \-i\ SEC \fR,\ \fB\-\-interval\ SEC
|
||||
Wait \fISEC\fR seconds between updates.
|
||||
The default is to update every second.
|
||||
The value of \fISEC\fR can be a decimal such as \*(lq0.1\*(rq.
|
||||
.TP
|
||||
.BI \-m\ SEC \fR,\ \fB\-\-average-rate-window\ SEC
|
||||
Compute current average rate over a \fISEC\fR seconds window for average
|
||||
rate and ETA calculations.
|
||||
The default is 30 seconds.
|
||||
The value must be an integer.
|
||||
.TP
|
||||
.BI \-w\ WIDTH \fR,\ \fB\-\-width\ WIDTH
|
||||
Assume the terminal is \fIWIDTH\fR columns wide, instead of autodetecting
|
||||
the width (or assuming 80 if detection fails).
|
||||
If this option is used, the output width will not be adjusted if the width
|
||||
of the terminal changes while the transfer is running.
|
||||
.TP
|
||||
.BI \-H\ HEIGHT \fR,\ \fB\-\-height\ HEIGHT
|
||||
Assume the terminal is \fIHEIGHT\fR rows high, instead of autodetecting
|
||||
the height (or assuming 25 if detection fails).
|
||||
If this option is used, the output height will not be adjusted if the height
|
||||
of the terminal changes while the transfer is running.
|
||||
.TP
|
||||
.BI \-N\ NAME \fR,\ \fB\-\-name\ NAME
|
||||
Prefix the output information with \fINAME\fR.
|
||||
Often used with \*(lq\fB\-\-cursor\fR\*(rq to identify each progress bar in
|
||||
a pipeline containing more than one \fBpv\fR.
|
||||
.TP
|
||||
.BI \-u\ STYLE \fR,\ \fB\-\-bar\-style\ STYLE
|
||||
Change the default progress bar style shown by \*(lq\fB\-\-progress\fR\*(rq,
|
||||
or by the \*(lq\fB\-\-format\fR\*(rq sequences \*(lq\fB%{progress}\fR\*(rq
|
||||
or \*(lq\fB%{progress\-bar\-only}\fR\*(rq, to \fISTYLE\fR.
|
||||
The \fISTYLE\fR can be one of \fBplain\fR (the default), \fBblock\fR,
|
||||
\fBgranular\fR, or \fBshaded\fR.
|
||||
These styles are described in the \fBFORMATTING\fR section below.
|
||||
.TP
|
||||
.BI \-x\ SPEC \fR,\ \fB\-\-extra\-display\ SPEC
|
||||
As well as displaying progress to the terminal, also write it to \fISPEC\fR.
|
||||
The \fISPEC\fR must start with a comma-separated list of destinations, and
|
||||
can optionally be followed by a colon and a format string.
|
||||
The destinations can be \fBwindowtitle\fR or \fBwindow\fR for the xterm
|
||||
window title, and \fBprocesstitle\fR, \fBproctitle\fR, \fBprocess\fR, or
|
||||
\fBproc\fR for the process title displayed by \fBps\fR(1).
|
||||
If a format string is not supplied, the same format is used as for the
|
||||
terminal.
|
||||
For example, \*(lq\fB\-x\~'window,process:%t\~%b\~%r'\fR\*(rq will show the
|
||||
elapsed time, bytes transferred, and rate, in both the window title and the
|
||||
process title.
|
||||
.TP
|
||||
.B \-9, \-\-conemu
|
||||
As well as displaying progress to the terminal, also emit the ConEmu
|
||||
"progress bar" sequences (OSC 9;4) to show the progress percentage in the
|
||||
terminal's title tab, on terminals which support it.
|
||||
This is equivalent to adding \*(lq%{progress\-conemu}\*(rq to the
|
||||
\fB\-\-format\fR string.
|
||||
.TP
|
||||
.B \-v, \-\-stats
|
||||
At the end of the transfer, write an additional line showing the transfer
|
||||
rate minimum, mean, maximum, and standard deviation.
|
||||
The values are always in bytes per second (or bits, with
|
||||
\*(lq\fB\-\-bits\fR\*(rq).
|
||||
.TP
|
||||
.B \-f, \-\-force
|
||||
Force output.
|
||||
Normally, \fBpv\fR will not output any visual display if standard error is
|
||||
not a terminal.
|
||||
This option forces it to do so.
|
||||
.TP
|
||||
.B \-c, \-\-cursor
|
||||
Use cursor positioning escape sequences to move to the initial terminal row
|
||||
when updating the display, instead of only using carriage returns.
|
||||
This allows multiple \fBpv\fR instances to show progress on the same
|
||||
terminal together.
|
||||
.IP
|
||||
For example:
|
||||
.IP
|
||||
.in +4
|
||||
.EX
|
||||
pv --cursor --name input file.gz | gzip -d | pv --cursor --name output > file
|
||||
.EE
|
||||
.in
|
||||
.IP
|
||||
As the example shows, this is often used with \*(lq\fB\-\-name\fR\*(rq.
|
||||
.\"
|
||||
.SS "Data transfer modifiers"
|
||||
.TP
|
||||
.BI \-o\ FILE \fR,\ \fB\-\-output\ FILE
|
||||
Write data to \fIFILE\fR instead of standard output.
|
||||
If the file already exists, it will be truncated.
|
||||
.TP
|
||||
.BI \-L\ RATE \fR,\ \fB\-\-rate-limit\ RATE
|
||||
Limit the transfer to a maximum of \fIRATE\fR bytes per second.
|
||||
The same suffixes as \*(lq\fB\-\-size\fR\*(rq can be used.
|
||||
Decimal values are allowed.
|
||||
Specifying 0 will turn off rate limiting, which is useful with
|
||||
\*(lq\fB\-\-remote\fR\*(rq.
|
||||
.TP
|
||||
.BI \-B\ BYTES \fR,\ \fB\-\-buffer-size\ BYTES
|
||||
Use a transfer buffer size of \fIBYTES\fR bytes.
|
||||
The same suffixes as \*(lq\fB\-\-size\fR\*(rq can be used.
|
||||
The default buffer size is the block size of the input file's filesystem
|
||||
multiplied by 32 (512KiB max), or 400KiB if the block size cannot be
|
||||
determined.
|
||||
This can be useful on platforms like macOS with pipelines that perform
|
||||
better with specific buffer sizes such as 1024.
|
||||
Implies \*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
.TP
|
||||
.B \-C, \-\-no-splice
|
||||
Prevent the use of \fBsplice\fR(2) and \fBcopy_file_range\fR(2), which are
|
||||
normally used on systems that support it to improve efficiency by
|
||||
eliminating the need for a transfer buffer.
|
||||
.IP
|
||||
In the default case that \fBsplice\fR(2) or \fBcopy_file_range\fR(2) are
|
||||
used, the lack of a transfer buffer prevents
|
||||
\*(lq\fB\-\-buffer\-percent\fR\*(rq and
|
||||
\*(lq\fB\-\-last\-written\fR\*(rq from working and makes
|
||||
\*(lq\fB\-\-buffer\-size\fR\*(rq redundant, so using any of those options
|
||||
automatically switches on \*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
.IP
|
||||
Sparse files cannot be written with \fBsplice\fR(2) or
|
||||
\fBcopy_file_range\fR(2), so using
|
||||
\*(lq\fB\-\-sparse\fR\*(rq automatically switches on
|
||||
\*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
.IP
|
||||
Switching on \*(lq\fB\-\-no\-splice\fR\*(rq results in a small loss of
|
||||
transfer efficiency.
|
||||
It has no effect on systems where \fBsplice\fR(2) and
|
||||
\fBcopy_file_range\fR(2) are unavailable.
|
||||
.TP
|
||||
.BI \-J\ BYTES \fR,\ \fB\-\-pipe\-buffer\-size\ BYTES
|
||||
Attempt to set the size of the output pipe buffer, and the intermediate
|
||||
input pipe buffer if one is needed, to \fIBYTES\fR bytes.
|
||||
This will silently do nothing if the requested size cannot be achieved.
|
||||
If this option is not specified, and both the output and the first input are
|
||||
pipes, then the output pipe buffer size will automatically be increased to
|
||||
match the input pipe buffer, if it was smaller.
|
||||
.TP
|
||||
.B \-E, \-\-skip-errors
|
||||
Ignore read errors by attempting to skip past the offending sections.
|
||||
The corresponding parts of the output will be null bytes.
|
||||
At first only a few bytes will be skipped, but if there are many errors in a
|
||||
row then the skips will move up to chunks of 512.
|
||||
This is intended to be similar to \*(lq\fIdd\~conv=sync,noerror\fR\*(rq.
|
||||
.IP
|
||||
Specify \*(lq\fB\-\-skip\-errors\fR\*(rq twice to only report a read error
|
||||
once per file, instead of reporting each byte range skipped.
|
||||
.TP
|
||||
.BI \-Z\ BYTES \fR,\ \fB\-\-error\-skip\-block\ BYTES
|
||||
When ignoring read errors with \*(lq\fB\-\-skip\-errors\fR\*(rq, instead of
|
||||
trying to adaptively skip by reading small amounts and skipping
|
||||
progressively larger sections until a read succeeds, move to the next file
|
||||
block of \fIBYTES\fR bytes as soon as an error occurs.
|
||||
There may still be some shorter skips where the block being skipped
|
||||
coincides with the end of the transfer buffer.
|
||||
The same suffixes as \*(lq\fB\-\-size\fR\*(rq can be used.
|
||||
.IP
|
||||
This option can only be used with \*(lq\fB\-\-skip\-errors\fR\*(rq
|
||||
and is intended for use when reading from a block device, such as
|
||||
\*(lq\fB\-\-skip\-errors\~\-\-error\-skip\-block\~4K\fR\*(rq
|
||||
to skip in 4 kibibyte blocks.
|
||||
This will speed up reads from faulty media, at the expense of potentially
|
||||
losing more data.
|
||||
.TP
|
||||
.B \-S, \-\-stop-at-size
|
||||
If a size was specified with \*(lq\fB\-\-size\fR\*(rq, stop transferring
|
||||
data once that many bytes have been written, instead of continuing to the
|
||||
end of input.
|
||||
.TP
|
||||
.B \-Y, \-\-sync
|
||||
After every write operation, synchronise the buffer caches to disk with
|
||||
\fBsync\fR(2), or \fBfdatasync\fR(2) if possible.
|
||||
This has no effect when the output is a pipe.
|
||||
Using \*(lq\fB\-\-sync\fR\*(rq may improve the accuracy of the progress bar
|
||||
when writing to a slow disk.
|
||||
.TP
|
||||
.B \-K, \-\-direct-io
|
||||
Set the \fBO_DIRECT\fR flag on all inputs and outputs, if it is available.
|
||||
This will minimise the effect of caches, at the cost of performance.
|
||||
Due to memory alignment requirements, it also may cause read or write
|
||||
failures with an error of \*(lqInvalid argument\*(rq, especially if reading
|
||||
and writing files across a variety of filesystems in a single \fBpv\fR call.
|
||||
Use this option with caution.
|
||||
.TP
|
||||
.B \-O, \-\-sparse
|
||||
When writing null bytes, try to seek, producing a sparse output file.
|
||||
Implies \*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
On filesystems without sparse file support, or when the output is not
|
||||
seekable, this option will have no effect other than to turn on
|
||||
\*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
.TP
|
||||
.B \-X, \-\-discard
|
||||
Instead of transferring input data to standard output, discard it.
|
||||
This is equivalent to redirecting standard output to \fI/dev/null\fR,
|
||||
except that \fBwrite\fR(2) is never called.
|
||||
.TP
|
||||
.BI \-U\ FILE \fR,\ \fB\-\-store\-and\-forward\ FILE
|
||||
Instead of passing data through immediately, do it in two stages - first
|
||||
read all input and write it to \fIFILE\fR, and then once the input is
|
||||
exhausted, read all of \fIFILE\fR and write it to the output.
|
||||
\fIFILE\fR remains in place afterwards, unless it is
|
||||
\*(lq\fB-\fR\*(rq, in which case \fBpv\fR creates a temporary file for this
|
||||
purpose, and automatically removes it afterwards.
|
||||
.IP
|
||||
A common use for this is this where one part of a pipeline generates data
|
||||
quickly but of unknown size, and the next part processes it slowly.
|
||||
With \*(lq\fIquick\fR\~\fB|\~pv\~\-U\~\-\~|\fR\~\fIslow\fR\*(rq, a progress
|
||||
bar is displayed with unknown size for the \fIquick\fR part, then a second
|
||||
is shown with a known size and ETA for the \fIslow\fR part.
|
||||
.\"
|
||||
.\"
|
||||
.SS "Alternative operating modes"
|
||||
.TP
|
||||
\fB\-d\fR, \fB\-\-watchfd\fR \fIPID\fR[:\fIFD\fR]|=\fINAME\fR|@\fILISTFILE\fR...
|
||||
Instead of transferring data, watch file descriptor \fIFD\fR of process
|
||||
\fIPID\fR, and show its progress.
|
||||
Other data transfer modifiers - and remote control - may not be used with
|
||||
this option.
|
||||
.IP
|
||||
If a \fIPID\fR is specified without an \fIFD\fR, then that process will be
|
||||
watched, and all regular files and block devices it opens will be shown with
|
||||
a progress bar.
|
||||
.IP
|
||||
If a \fINAME\fR is specified, prefixed with "=", then processes with that
|
||||
name will be found with \fBpgrep\fR(1), and as watched described above.
|
||||
.IP
|
||||
If a \fILISTFILE\fR is specified, prefixed with "@", the lines in that file
|
||||
will be used as additional arguments.
|
||||
.IP
|
||||
All remaining non-option arguments will also be treated as additional
|
||||
arguments.
|
||||
.IP
|
||||
The \fBpv\fR process will exit when all \fIFD\fRs have either changed to a
|
||||
different file, changed read/write mode, or have closed, and all \fIPID\fRs
|
||||
(without a specific \fIFD\fR) have exited.
|
||||
.TP
|
||||
.BI \-R\ PID \fR,\ \fB\-\-remote\ PID
|
||||
Remotely control another instance of \fBpv\fR with process ID \fIPID\fR,
|
||||
making it act as though it had been given this instance's command line.
|
||||
For example, if \*(lq\fBpv\~\-\-rate\-limit\~123K\fR\*(rq is running with
|
||||
process ID 9876, then running
|
||||
\*(lq\fBpv\~\-\-remote\~9876\~\-\-rate\-limit\~321K\fR\*(rq will cause
|
||||
process 9876 to start using a rate limit of 321KiB instead of 123KiB.
|
||||
Note that some options cannot be changed while running, such as
|
||||
\*(lq\fB\-\-cursor\fR\*(rq, \*(lq\fB\-\-line\-mode\fR\*(rq,
|
||||
\*(lq\fB\-\-force\fR\*(rq, \*(lq\fB\-\-delay\-start\fR\*(rq,
|
||||
\*(lq\fB\-\-skip\-errors\fR\*(rq, and \*(lq\fB\-\-stop\-at\-size\fR\*(rq.
|
||||
.TP
|
||||
.BI \-Q\ PID \fR,\ \fB\-\-query\ PID
|
||||
Display the transfer progress of another instance of \fBpv\fR with process
|
||||
ID \fIPID\fR, owned by the same user.
|
||||
.IP
|
||||
Some output modifiers can only be used while querying another process if
|
||||
they match those of that process - such as
|
||||
\*(lq\fB\-\-line\-mode\fR\*(rq,
|
||||
\*(lq\fB\-\-null\fR\*(rq, and
|
||||
\*(lq\fB\-\-average\-rate\-window\fR\*(rq.
|
||||
Data transfer modifiers will have no effect.
|
||||
.TP
|
||||
.BR \-M " \fISIDE\fR, " \-\-monitor " \fISIDE\fR"
|
||||
Run the command specified by the remaining arguments, and monitor its
|
||||
standard input, its standard output, or both, depending on whether
|
||||
\fISIDE\fR is \*(lq\fBin\fR\*(rq, \*(lq\fBout\fR\*(rq, or
|
||||
\*(lq\fBboth\fR\*(rq.
|
||||
Use \*(lq\fB\-\-\fR\*(rq after all of the \fBpv\fR options to keep the
|
||||
monitored command's options separate.
|
||||
.IP
|
||||
With a \fISIDE\fR of \*(lq\fBboth\fR\*(rq, two progress bars will be shown.
|
||||
All of \fBpv\fR's display switches, output modifiers, and data transfer
|
||||
modifiers will apply to both sides.
|
||||
.IP
|
||||
For example,
|
||||
\*(lq\fBpv\~\-\-cursor\~\-\-monitor\~both\~\-\-\~gzip\~\-9\fR\*(rq is
|
||||
equivalent to
|
||||
\*(lq\fBpv\~\-\-cursor\~|\~gzip\~\-9\~|\~pv\~\-\-cursor\fR\*(rq, except that
|
||||
the latter can't show the input:output ratio.
|
||||
.IP
|
||||
The \*(lq\fB\-\-format\fR\*(rq and \*(lq\fB\-\-name\fR\*(rq options may be
|
||||
specified twice, in which case the first one applies to the input side and
|
||||
the second applies to the output side.
|
||||
If no \*(lq\fB\-\-format\fR\*(rq options are specified, the default format
|
||||
based on the other display switches is used as normal, except that the
|
||||
ratio is added to the output side when \fISIDE\fR is \*(lq\fBboth\fR\*(rq.
|
||||
.IP
|
||||
The values \*(lq\fB0\fR\*(rq, \*(lq\fB1\fR\*(rq, and \*(lq\fB2\fR\*(rq may
|
||||
be used as synonyms for \*(lq\fBin\fR\*(rq, \*(lq\fBout\fR\*(rq, and
|
||||
\*(lq\fBboth\fR\*(rq.
|
||||
.IP
|
||||
This option cannot be used with \*(lq\fB\-\-store\-and\-forward\*(rq.
|
||||
.\"
|
||||
.SS "Other options"
|
||||
.TP
|
||||
.BI \-P\ FILE \fR,\ \fB\-\-pidfile\ FILE
|
||||
Save the process ID of \fBpv\fR in \fIFILE\fR.
|
||||
The file will be replaced if it already exists, and will be removed when
|
||||
\fBpv\fR exits.
|
||||
While \fBpv\fR is running, \fIFILE\fR will contain a single number - the
|
||||
process ID of \fBpv\fR - followed by a newline.
|
||||
.TP
|
||||
.B \-h, \-\-help
|
||||
Print a usage message on standard output and exit successfully.
|
||||
.TP
|
||||
.B \-V, \-\-version
|
||||
Print version information on standard output and exit successfully.
|
||||
.\"
|
||||
.SH FORMATTING
|
||||
Format strings used by \*(lq\fB\-\-format\fR\*(rq and
|
||||
\*(lq\fB\-\-extra\-display\fR\*(rq can contain the following sequences:
|
||||
.TP
|
||||
.BR %p ", " %{progress}
|
||||
Progress bar (suffixed with a percentage if the size is known).
|
||||
Equivalent to \*(lq\fB\-\-progress\fR\*(rq.
|
||||
Expands to fill the remaining space unless prefixed by a number to set the
|
||||
width, such as \*(lq\fB%20p\fR\*(rq or \*(lq\fB%20{progress}\fR\*(rq.
|
||||
.TP
|
||||
.BR %{progress\-bar\-only}
|
||||
Progress bar, without any sides, and without any percentage displayed
|
||||
afterwards.
|
||||
Expands to fill the remaining space unless prefixed by a number.
|
||||
.TP
|
||||
.B %{progress\-amount\-only}
|
||||
The percentage completion (or maximum rate, with \*(lq\fB\-\-gauge\fR\*(rq
|
||||
when the size is unknown).
|
||||
.TP
|
||||
.B %{progress-conemu}
|
||||
Emit the ConEmu "progress bar" sequences (OSC 9;4) to show the progress
|
||||
percentage in the terminal's title tab, on terminals which support it.
|
||||
.TP
|
||||
.B %{bar\-plain}
|
||||
Progress bar in the standard plain format, without any sides, and without
|
||||
any percentage displayed afterwards.
|
||||
Expands to fill the remaining space unless prefixed by a number.
|
||||
.TP
|
||||
.B %{bar\-block}
|
||||
Progress bar using Unicode full blocks, without any sides, and without any
|
||||
percentage displayed afterwards.
|
||||
Expands to fill the remaining space unless prefixed by a number.
|
||||
If UTF-8 output is not available, the plain format is used.
|
||||
.TP
|
||||
.B %{bar\-granular}
|
||||
Progress bar using Unicode full blocks, and 1/8th blocks for partial fills,
|
||||
providing a more granular display.
|
||||
Like the other \*(lq%{bar}\*(rq strings this shows the bar without any
|
||||
sides, and without any percentage displayed afterwards, and expands to fill
|
||||
the remaining space unless prefixed by a number.
|
||||
If UTF-8 output is not available, the plain format is used.
|
||||
.TP
|
||||
.B %{bar\-shaded}
|
||||
Progress bar using Unicode full blocks and shade characters - dark and
|
||||
medium shade are used for partial fills, and the light shade is used for the
|
||||
background.
|
||||
Like the other \*(lq%{bar}\*(rq strings this shows the bar without any
|
||||
sides, and without any percentage displayed afterwards, and expands to fill
|
||||
the remaining space unless prefixed by a number.
|
||||
If UTF-8 output is not available, the plain format is used.
|
||||
.TP
|
||||
.BR %t ", " %{timer}
|
||||
Elapsed time.
|
||||
Equivalent to \*(lq\fB\-\-timer\fR\*(rq.
|
||||
.TP
|
||||
.BR %e ", " %{eta}
|
||||
ETA as time remaining.
|
||||
Equivalent to \*(lq\fB\-\-eta\fR\*(rq.
|
||||
.TP
|
||||
.BR %I ", " %{fineta}
|
||||
ETA as local time at which the transfer will finish.
|
||||
Equivalent to \*(lq\fB\-\-fineta\fR\*(rq.
|
||||
.TP
|
||||
.BR %r ", " %{rate}
|
||||
Current data transfer rate.
|
||||
Equivalent to \*(lq\fB\-\-rate\fR\*(rq.
|
||||
.TP
|
||||
.BR %a ", " %{average\-rate}
|
||||
Average data transfer rate.
|
||||
Equivalent to \*(lq\fB\-\-average\-rate\fR\*(rq.
|
||||
.TP
|
||||
.BR %b ", " %{bytes} ", " %{transferred}
|
||||
Bytes transferred so far (or lines if \*(lq\fB\-\-line\-mode\fR\*(rq was specified).
|
||||
Equivalent to \*(lq\fB\-\-bytes\fR\*(rq.
|
||||
If \*(lq\fB\-\-bits\fR\*(rq was specified, \*(lq\fB%b\fR\*(rq shows the bits
|
||||
transferred so far, not bytes.
|
||||
.TP
|
||||
.B %{ratio}
|
||||
Show the ratio of bytes transferred by the other side to the bytes
|
||||
transferred by this side, in \*(lq\fB\-\-monitor\~both\fR\*(rq mode.
|
||||
.TP
|
||||
.BR %T ", " %{buffer\-percent}
|
||||
Percentage of the transfer buffer in use.
|
||||
Equivalent to \*(lq\fB\-\-buffer\-percent\fR\*(rq, but using it does not
|
||||
turn on \*(lq\fB\-\-no\-splice\fR\*(rq.
|
||||
.IP
|
||||
If the transfer is using \fBsplice\fR(2), displays \*(lq{\-\-\-\-}\*(rq; if
|
||||
the transfer is using \fBsplice\fR(2) via an intermediate input pipe,
|
||||
displays \*(lq{\-||\-}\*(rq; and if the transfer is using
|
||||
\fBcopy_file_range\fR(2), displays \*(lq{\-\-\->}\*(rq.
|
||||
.TP
|
||||
.BR %nA ", " %n{last\-written}
|
||||
Show the last \fIn\fR bytes written (for example, \*(lq\fB%16A\fR\*(rq shows
|
||||
the last 16 bytes).
|
||||
Shows only dots if the transfer is using \fBsplice\fR(2) or
|
||||
\fBcopy_file_range\fR(2), since these transfer modes do not use the buffer.
|
||||
.TP
|
||||
.BR %nL ", " %n{previous\-line}
|
||||
Show the first \fIn\fR bytes of the most recently written line (for example,
|
||||
\*(lq\fB%40L\fR\*(rq shows the first 40 bytes).
|
||||
If no \fIn\fR is given, then this expands to fill the available space.
|
||||
Shows only spaces if the transfer is using \fBsplice\fR(2) or
|
||||
\fBcopy_file_range\fR(2).
|
||||
.TP
|
||||
.BR %N ", " %{name}
|
||||
Show the name prefix given by \*(lq\fB\-\-name\fR\*(rq.
|
||||
Padded to 9 characters with spaces, and suffixed with \*(lq:\*(rq.
|
||||
.TP
|
||||
.B %{sgr:colour,...}
|
||||
Emit ECMA-48 SGR (Select Graphic Rendition) codes if the terminal supports
|
||||
colours, where \fIcolour,...\fR is a comma-separated list of any of the
|
||||
keywords below, or the numeric values from \fBconsole_codes\fR(4). If
|
||||
colour support is not available, nothing is emitted.
|
||||
.IP
|
||||
Supported keywords are:
|
||||
\fBreset\fR or \fBnone\fR,
|
||||
\fBblack\fR,
|
||||
\fBred\fR,
|
||||
\fBgreen\fR,
|
||||
\fBbrown\fR or \fByellow\fR,
|
||||
\fBblue\fR,
|
||||
\fBmagenta\fR,
|
||||
\fBcyan\fR,
|
||||
\fBwhite\fR,
|
||||
\fBfg\-black\fR,
|
||||
\fBfg\-red\fR,
|
||||
\fBfg\-green\fR,
|
||||
\fBfg\-brown\fR or \fBfg\-yellow\fR,
|
||||
\fBfg\-blue\fR,
|
||||
\fBfg\-magenta\fR,
|
||||
\fBfg\-cyan\fR,
|
||||
\fBfg\-white\fR,
|
||||
\fBfg\-default\fR,
|
||||
\fBbg\-black\fR,
|
||||
\fBbg\-red\fR,
|
||||
\fBbg\-green\fR,
|
||||
\fBbg\-brown\fR or \fBbg\-yellow\fR,
|
||||
\fBbg\-blue\fR,
|
||||
\fBbg\-magenta\fR,
|
||||
\fBbg\-cyan\fR,
|
||||
\fBbg\-white\fR,
|
||||
\fBbg\-default\fR,
|
||||
\fBbold\fR,
|
||||
\fBdim\fR,
|
||||
\fBitalic\fR,
|
||||
\fBunderscore\fR or \fBunderline\fR,
|
||||
\fBblink\fR,
|
||||
\fBreverse\fR,
|
||||
\fBno\-bold\fR or \fBno\-dim\fR,
|
||||
\fBno\-italic\fR,
|
||||
\fBno\-underscore\fR or \fBno\-underline\fR,
|
||||
\fBno\-blink\fR,
|
||||
\fBno\-reverse\fR.
|
||||
.IP
|
||||
With colours, the optional "fg-" prefix indicates foreground; a prefix of
|
||||
"bg-" indicates background.
|
||||
.IP
|
||||
For example, \*(lq\fB%{sgr:green,bold}TEXT%{sgr:reset}\fR\*(lq will make
|
||||
\fITEXT\fR bold green on supported terminals.
|
||||
.TP
|
||||
.B %%
|
||||
A single \*(lq%\*(rq.
|
||||
.PP
|
||||
Any other contents are reproduced in the progress display as-is.
|
||||
.PP
|
||||
The format string equivalent of the default display switches is
|
||||
\*(lq\fB%b\~%t\~%r\~%p\~%e\fR\*(rq.
|
||||
.\"
|
||||
.SH EXAMPLES
|
||||
Some suggested common switch combinations:
|
||||
.TP
|
||||
.B pv \-ptebar
|
||||
Show a progress bar, elapsed time, estimated completion time, byte counter,
|
||||
average rate, and current rate.
|
||||
.TP
|
||||
.B pv \-betlap
|
||||
Show a progress bar, elapsed time, estimated completion time, line counter,
|
||||
and average rate, counting lines instead of bytes.
|
||||
.TP
|
||||
.B pv \-btrpg
|
||||
Show the amount transferred, elapsed time, current rate, and a gauge showing
|
||||
the current rate as a percentage of the maximum rate seen - useful in a
|
||||
pipeline where the total size is unknown.
|
||||
(If the size \fIis\fR known, these options will show the percentage
|
||||
completion instead of the rate gauge).
|
||||
.TP
|
||||
.B pv \-t
|
||||
Show only the elapsed time - useful as a simple timer, such as
|
||||
\*(lq\fBsleep\~10m\~|\~pv\~\-t\fR\*(rq.
|
||||
.TP
|
||||
.B pv \-pterb
|
||||
The default behaviour: progress bar, elapsed time, estimated completion
|
||||
time, current rate, and byte counter.
|
||||
.TP
|
||||
.B pv \-\-format='%{progress-conemu}%{bytes} %{timer} %{rate} %{progress} %{eta}'
|
||||
Show the byte counter, elapsed time, current rate, progress bar, and ETA,
|
||||
and show the percentage progress in the terminal's tab bar, on terminals
|
||||
that support ConEmu OSC 9;4 sequences.
|
||||
.PP
|
||||
On macOS, it may be useful to specify \*(lq\fB\-\-buffer\-size\~1024\fR\*(rq
|
||||
in a pipeline, as this may improve performance.
|
||||
.PP
|
||||
To watch how quickly a file is transferred using \fBnc\fR(1):
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv file | nc \-w 1 somewhere.com 3000
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
A similar example, transferring a file from another process and passing the
|
||||
expected size to \fBpv\fR:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
cat file | pv \-\-size 12345 | nc \-w 1 somewhere.com 3000
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
To watch the progress of creating a tar.gz archive:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
tar cf \- directory/ \e
|
||||
| pv \-\-size $(du \-sb directory/ | awk '{print $1}') \e
|
||||
| gzip \-9 \e
|
||||
> out.tar.gz
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
An alternative way of doing the same thing:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
tar cf \- directory/ \e
|
||||
| pv \-\-size @directory/ \e
|
||||
| gzip \-9 \e
|
||||
> out.tar.gz
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Taking an image of a disk, skipping errors:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv \-EE /dev/your/disk/device > disk-image.img
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Writing an image back to a disk:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv disk-image.img > /dev/your/disk/device
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Zeroing a disk:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv < /dev/zero > /dev/your/disk/device
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Note that if the input size cannot be calculated, and the output is a block
|
||||
device, then the size of the block device will be used and \fBpv\fR will
|
||||
automatically stop at that size as if \*(lq\fB\-\-stop\-at\-size\fR\*(rq had
|
||||
been given.
|
||||
.PP
|
||||
(Linux and macOS only): Watching file descriptor 3 opened by another process 1234:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv \-\-watchfd 1234:3
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
(Linux and macOS only): Watching all file descriptors used by process 1234:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv \-\-watchfd 1234
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Rate-limiting the transfer between two processes in a pipeline, with no
|
||||
display:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
producer | pv \-\-quiet \-\-rate\-limit 1M | consumer
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Sending logs to a processing script, showing the most recent line as part of
|
||||
the progress display:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv \-\-no\-splice \-\-format '%a %p : %L' big.log | processing-script
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Showing progress as lines of JSON data:
|
||||
.PP
|
||||
.in +4
|
||||
.EX
|
||||
pv \-\-numeric \-\-format '{"elapsed":%t,"bytes":%b,"rate":%r,"percentage":%{progress-amount-only}}' big.log | processing-script
|
||||
.EE
|
||||
.in
|
||||
.\"
|
||||
.SH EXIT STATUS
|
||||
An exit status of 1 indicates a problem with the \*(lq\fB\-\-remote\fR\*(rq,
|
||||
\*(lq\fB\-\-query\fR\*(rq, \*(lq\fB\-\-pidfile\fR\*(rq, or
|
||||
\*(lq\fB\-\-monitor\fR\*(rq options.
|
||||
.PP
|
||||
Any other exit status is a bitmask of the following:
|
||||
.TP 5
|
||||
\~\fB2\fR
|
||||
One or more files could not be accessed, \fBstat\fR(2)ed, or opened.
|
||||
.TP
|
||||
\~\fB4\fR
|
||||
An input file was the same as the output file.
|
||||
.TP
|
||||
\~\fB8\fR
|
||||
Internal error with closing a file or moving to the next file.
|
||||
.TP
|
||||
\~\fB16\fR
|
||||
There was an error while transferring data from one or more input files.
|
||||
.TP
|
||||
\~\fB32\fR
|
||||
A signal was caught that caused an early exit.
|
||||
.TP
|
||||
\~\fB64\fR
|
||||
Memory allocation failed.
|
||||
.PP
|
||||
A zero exit status indicates no problems.
|
||||
.\"
|
||||
.SH ENVIRONMENT
|
||||
The following environment variables may affect \fBpv\fR:
|
||||
.TP
|
||||
.B HOME
|
||||
The current user's home directory.
|
||||
This may be used by \*(lq\fB\-\-remote\fR\*(rq and \*(lq\fB\-\-query\fR\*(rq
|
||||
to exchange messages between \fBpv\fR instances: if the \fI/run/user/UID/\fR
|
||||
directory does not exist (where \fIUID\fR is the current user ID), then
|
||||
\fI$HOME/.pv/\fR will be used instead.
|
||||
.TP
|
||||
.BR TMPDIR ", " TMP
|
||||
The directory to create per-tty lock files for the terminal when using
|
||||
\*(lq\fB\-\-cursor\fR\*(rq.
|
||||
If \fBTMPDIR\fR is set to a non-empty value, it is the directory under which
|
||||
lock files are created.
|
||||
Otherwise, \fBTMP\fR is used.
|
||||
If neither are set, then \fI/tmp\fR is used.
|
||||
.\"
|
||||
.SH NOTES
|
||||
In some versions of \fBbash\fR(1) and \fBzsh\fR(1), the construct
|
||||
\*(lq\fB<(pv\~filename)\fR\*(rq will not output any progress to the terminal
|
||||
when run from an interactive shell, due to the subprocess being run in a
|
||||
separate process group from the one that owns the terminal.
|
||||
In these cases, use \*(lq\fB\-\-force\fR\*(rq.
|
||||
.PP
|
||||
If \fBpv\fR is used in a pipeline in \fBzsh\fR version 5.8, and the last
|
||||
command in the pipeline is based on shell builtins, \fBzsh\fR takes control
|
||||
of the terminal away from \fBpv\fR, preventing progress from being
|
||||
displayed.
|
||||
For example, this will produce no progress bar:
|
||||
.PP
|
||||
.in +4n
|
||||
.EX
|
||||
pv InputFile | { while read \-r line; do sleep 0.1; done; }
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
To work around this, put the last commands of the pipeline in
|
||||
normal brackets to force the use of a subshell:
|
||||
.PP
|
||||
.in +4n
|
||||
.EX
|
||||
pv InputFile | ( while read \-r line; do sleep 0.1; done; )
|
||||
.EE
|
||||
.in
|
||||
.PP
|
||||
Refer to
|
||||
.UR https://codeberg.org/ivarch/pv/issues/105
|
||||
issue #105
|
||||
.UE
|
||||
for full details.
|
||||
.PP
|
||||
The \*(lq\fB\-\-remote\fR\*(rq and \*(lq\fB\-\-query\fR\*(rq options require
|
||||
that either \fI/run/user/<uid>/\fR or \fI$HOME/\fR can be written to, for
|
||||
inter-process communication.
|
||||
.PP
|
||||
The \*(lq\fB\-\-size\fR\*(rq option has no effect if used with
|
||||
\*(lq\fB\-\-watchfd\fR\~\fIPID\fR\*(rq to watch all file descriptors of a
|
||||
process, but will work with \*(lq\fB\-\-watchfd\fR\~\fIPID\fR:\fIFD\fR\*(rq
|
||||
to watch a single file descriptor.
|
||||
.PP
|
||||
If the input size cannot be calculated, and the output is a block device,
|
||||
then \fBpv\fR will read the output device's size, use that as if it had been
|
||||
passed to \*(lq\fB\-\-size\fR\*(rq, and activate
|
||||
\*(lq\fB\-\-stop\-at\-size\fR\*(rq.
|
||||
.PP
|
||||
The \*(lq\fB%nA\fR\*(rq and \*(lq\fB%nL\fR\*(rq format sequences may not be
|
||||
effective with small input files, and \*(lq\fB%nL\fR\*(rq may be a few lines
|
||||
out due to buffering within the pipeline itself.
|
||||
.PP
|
||||
Numbers passed to \*(lq\fB\-\-size\fR\*(rq,
|
||||
\*(lq\fB\-\-buffer\-size\fR\*(rq, \*(lq\fB\-\-pipe\-buffer\-size\fR\*(rq,
|
||||
and \*(lq\fB\-\-error\-skip\-block\fR\*(rq may all be expressed as decimals
|
||||
if followed by a suffix, so for example \*(lq\fI\-\-size\~1.5G\fR\*(rq is
|
||||
equivalent to \*(lq\fI\-\-size\~1536M\fR\*(rq.
|
||||
.PP
|
||||
Numbers passed to \*(lq\fB\-\-rate\-limit\fR\*(rq may be expressed as
|
||||
decimals with or without a suffix.
|
||||
.PP
|
||||
Numbers passed to \*(lq\fB\-\-interval\fR\*(rq and
|
||||
\*(lq\fB\-\-delay\-start\fR\*(rq may be integers or decimals, but may not
|
||||
have a suffix.
|
||||
.PP
|
||||
Numbers passed to \*(lq\fB\-\-last\-written\fR\*(rq,
|
||||
\*(lq\fB\-\-width\fR\*(rq, \*(lq\fB\-\-height\fR\*(rq,
|
||||
\*(lq\fB\-\-average\-rate\-window\fR\*(rq, \*(lq\fB\-\-remote\fR\*(rq, and
|
||||
\*(lq\fB\-\-query\fR\*(rq must be integers with no suffix.
|
||||
.PP
|
||||
When \*(lq\fB\-\-sparse\fR\*(rq is in effect and output is being written to
|
||||
a file, that file may look like it has stopped growing if inspected with
|
||||
\fBls\fR(1) while null bytes are being written, even though \fBpv\fR still
|
||||
reports progress.
|
||||
This is because of the way sparse output is achieved, and the file will be
|
||||
the correct size when the transfer ends.
|
||||
.\"
|
||||
.SH REPORTING BUGS
|
||||
Please report bugs or feature requests via the issue tracker linked from the
|
||||
.UR https://ivarch.com/p/pv
|
||||
\fBpv\fR home page
|
||||
.UE .
|
||||
.\"
|
||||
.SH "SEE ALSO"
|
||||
.BR cat (1),
|
||||
.BR splice (2),
|
||||
.BR copy_file_range (2),
|
||||
.BR fsync (2),
|
||||
.BR fdatasync (2),
|
||||
.BR open (2)
|
||||
(for \fBO_DIRECT\fR),
|
||||
.BR console_codes (4)
|
||||
.\"
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood.
|
||||
.PP
|
||||
License GPLv3+:
|
||||
.UR https://www.gnu.org/licenses/gpl-3.0.html
|
||||
GNU GPL version 3 or later
|
||||
.UE .
|
||||
.PP
|
||||
This is free software: you are free to change and redistribute it. There is
|
||||
NO WARRANTY, to the extent permitted by law.
|
||||
.PP
|
||||
Please see the package's ACKNOWLEDGEMENTS file for a complete list of
|
||||
contributors.
|
||||
+905
@@ -0,0 +1,905 @@
|
||||
# NAME
|
||||
|
||||
pv - monitor and manage the progress of data through a pipe
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
**pv** \[*OPTION*\]\... \[*FILE*\]\...
|
||||
|
||||
**pv** \[*OPTION*\]\... **-d**\|**\--watchfd**
|
||||
*PID*\[:*FD*\]\|=*NAME*\|@*LISTFILE*\...
|
||||
|
||||
**pv** **-R**\|**\--remote** *PID* \[*OPTION*\]\...
|
||||
|
||||
**pv** **-Q**\|**\--query** *PID* \[*OPTION*\]\...
|
||||
|
||||
**pv** \[*OPTION*\]\... **-M**\|**\--monitor** *SIDE* \-- *COMMAND*
|
||||
[*ARGS*\]\...
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Show the progress of data through a pipeline by giving information such
|
||||
as time elapsed, percentage completed (with progress bar), current
|
||||
throughput rate, total data transferred, and ETA. The data flow rate,
|
||||
error handling strategy, buffer size, and cache interaction can all be
|
||||
adjusted.
|
||||
|
||||
Each *FILE* is copied to standard output. With no *FILE*, or when *FILE*
|
||||
is "-", standard input is read.
|
||||
|
||||
In "**\--watchfd**" mode, inspect another process and show its progress
|
||||
through the files it has open.
|
||||
|
||||
In "**\--monitor**" mode, run a command and display the progress of data
|
||||
through both its standard input and its standard output.
|
||||
|
||||
# OPTIONS
|
||||
|
||||
## Display switches
|
||||
|
||||
If no display switches are specified, **pv** behaves as if
|
||||
"**\--progress**", "**\--timer**", "**\--eta**", "**\--rate**", and
|
||||
"**\--bytes**" had been given. Otherwise, only those display types that
|
||||
are explicitly switched on will be shown.
|
||||
|
||||
**-p, \--progress**
|
||||
|
||||
: Turn the progress bar on. If any inputs are not files, or are
|
||||
unreadable, and no size was explicitly given with "**\--size**", the
|
||||
progress bar cannot indicate how close to completion the transfer
|
||||
is, so it will just move left and right to indicate that data is
|
||||
moving - or, with "**\--gauge**", the bar will indicate the current
|
||||
rate as a percentage of the maximum rate seen so far.
|
||||
|
||||
**-t, \--timer**
|
||||
|
||||
: Turn the timer on. This will display the total elapsed time that
|
||||
**pv** has been running for.
|
||||
|
||||
**-e, \--eta**
|
||||
|
||||
: Turn the ETA countdown on. This will estimate, based on current
|
||||
transfer rates and the total data size, how long it will be before
|
||||
completion. The countdown is prefixed with "ETA". This option will
|
||||
have no effect if the total data size cannot be determined.
|
||||
|
||||
**-I, \--fineta**
|
||||
|
||||
: Turn the ETA countdown on, but display the estimated local time at
|
||||
which the transfer will finish, instead of the amount of time
|
||||
remaining. When the estimated time is more than 6 hours in the
|
||||
future, the date is shown as well. The time is prefixed with "FIN"
|
||||
for finish time. As with "**\--eta**", this option will have no
|
||||
effect if the total data size cannot be determined.
|
||||
|
||||
**-r, \--rate**
|
||||
|
||||
: Turn the rate counter on. This will display the current rate of data
|
||||
transfer. The rate is shown in square brackets "\[\]".
|
||||
|
||||
**-a, \--average-rate**
|
||||
|
||||
: Turn the average rate counter on. This will display the current
|
||||
average rate of data transfer, over the last 30 seconds by default
|
||||
(see "**\--average-rate-window**"). The average rate is shown in
|
||||
brackets "()".
|
||||
|
||||
**-b, \--bytes**
|
||||
|
||||
: Turn the total byte counter on. This will display the total amount
|
||||
of data transferred so far.
|
||||
|
||||
**-T, \--buffer-percent**
|
||||
|
||||
: Turn on the transfer buffer percentage display. This will show the
|
||||
percentage of the transfer buffer in use. Implies
|
||||
"**\--no-splice**". The transfer buffer percentage is shown in curly
|
||||
brackets "{}".
|
||||
|
||||
**-A NUM, \--last-written NUM**
|
||||
|
||||
: Show the last *NUM* bytes written. Implies "**\--no-splice**".
|
||||
|
||||
**-F FORMAT, \--format FORMAT**
|
||||
|
||||
: Ignore all of the above options and instead use the format string
|
||||
*FORMAT* to determine the output format. See the **FORMATTING**
|
||||
section below.
|
||||
|
||||
**-n, \--numeric**
|
||||
|
||||
: Numeric output. Instead of giving a visual indication of progress,
|
||||
write an integer percentage, one per line, on standard error,
|
||||
suitable for passing to a tool such as **dialog**(1). Note that
|
||||
"**\--force**" is not required if "**\--numeric**" is being used.
|
||||
|
||||
Combining "**\--numeric**" with "**\--bytes**" will cause the number
|
||||
of bytes processed so far to be output instead of a percentage.
|
||||
Adding "**\--line-mode**" as well as "**\--bytes**" writes the
|
||||
number of lines instead of bytes or a percentage. Adding
|
||||
"**\--rate**" adds the transfer rate to each output line (if
|
||||
"**\--bytes**" is also in use, the rate comes after the byte/line
|
||||
count). Adding "**\--timer**" prefixes each output line with the
|
||||
elapsed time so far, as a decimal number of seconds.
|
||||
|
||||
Combining "**\--numeric**" with "**\--format**" allows for custom
|
||||
output. The default format string components for "**\--numeric**"
|
||||
are "**%t %b %r %{progress-amount-only}**" in that order, each item
|
||||
being active or inactive according to the rules above (so the
|
||||
default with no other options is "**%{progress-amount-only}**").
|
||||
|
||||
**-q, \--quiet**
|
||||
|
||||
: No output. Useful if the "**\--rate-limit**" option is being used on
|
||||
its own to limit the transfer rate of a pipe.
|
||||
|
||||
## Output modifiers
|
||||
|
||||
**-8, \--bits**
|
||||
|
||||
: Use bits instead of bytes for the byte and rate counters. The output
|
||||
suffix will be "b" instead of "B".
|
||||
|
||||
**-k, \--si**
|
||||
|
||||
: Display and interpret suffixes as multiples of 1000 rather than the
|
||||
default of 1024. Note that this only takes effect on options after
|
||||
this one, so for consistency, specify this option first.
|
||||
|
||||
**-W, \--wait**
|
||||
|
||||
: Wait until the first byte has been transferred before showing any
|
||||
progress information or calculating any ETAs. For example, use this
|
||||
option when piping data into tools such as **gpg**(1) or
|
||||
"**mysql -p**" so the count only starts after the password prompt
|
||||
has been answered.
|
||||
|
||||
**-D SEC, \--delay-start SEC**
|
||||
|
||||
: Wait until *SEC* seconds have passed before showing any progress
|
||||
information, so that a transfer that is over quickly won\'t display
|
||||
anything. The value of *SEC* can be a decimal such as "0.5".
|
||||
|
||||
**-s SIZE, \--size SIZE**
|
||||
|
||||
: Assume the total amount of data to be transferred is *SIZE* bytes
|
||||
when calculating percentages and ETAs. A suffix of "K", "M", "G", or
|
||||
"T" can be added to denote kibibytes (\*1024), mebibytes, gibibytes,
|
||||
tebibytes. If "**\--si**" appears before this option, suffixes will
|
||||
denote kilobytes (\*1000), megabytes, and so on instead.
|
||||
|
||||
If *SIZE* starts with "**@**", the size of file whose name follows
|
||||
the @ will be used; if that is a directory, the size of all files
|
||||
under it will be used, like "**du \--apparent-size -b**".
|
||||
|
||||
**-g, \--gauge**
|
||||
|
||||
: If the progress bar is shown but the size is not known, then instead
|
||||
of moving the bar left and right to show progress, show the current
|
||||
transfer rate as a percentage of the maximum rate seen so far.
|
||||
|
||||
**-l, \--line-mode**
|
||||
|
||||
: Instead of counting bytes, count lines (newline characters). The
|
||||
progress bar will only move when a new line is found, and the value
|
||||
passed to "**\--size**" will be interpreted as a line count.
|
||||
|
||||
If this option is used without "**\--size**", the \"total size\" (in
|
||||
this case, total line count) is calculated by reading through all
|
||||
input files once before transfer starts. If any inputs are pipes or
|
||||
non-regular files, or are unreadable, the total size will not be
|
||||
calculated.
|
||||
|
||||
**-0, \--null**
|
||||
|
||||
: Count lines as terminated with a null byte instead of with a
|
||||
newline. This option implies "**\--line-mode**".
|
||||
|
||||
**-i SEC, \--interval SEC**
|
||||
|
||||
: Wait *SEC* seconds between updates. The default is to update every
|
||||
second. The value of *SEC* can be a decimal such as "0.1".
|
||||
|
||||
**-m SEC, \--average-rate-window SEC**
|
||||
|
||||
: Compute current average rate over a *SEC* seconds window for average
|
||||
rate and ETA calculations. The default is 30 seconds. The value must
|
||||
be an integer.
|
||||
|
||||
**-w WIDTH, \--width WIDTH**
|
||||
|
||||
: Assume the terminal is *WIDTH* columns wide, instead of
|
||||
autodetecting the width (or assuming 80 if detection fails). If this
|
||||
option is used, the output width will not be adjusted if the width
|
||||
of the terminal changes while the transfer is running.
|
||||
|
||||
**-H HEIGHT, \--height HEIGHT**
|
||||
|
||||
: Assume the terminal is *HEIGHT* rows high, instead of autodetecting
|
||||
the height (or assuming 25 if detection fails). If this option is
|
||||
used, the output height will not be adjusted if the height of the
|
||||
terminal changes while the transfer is running.
|
||||
|
||||
**-N NAME, \--name NAME**
|
||||
|
||||
: Prefix the output information with *NAME*. Often used with
|
||||
"**\--cursor**" to identify each progress bar in a pipeline
|
||||
containing more than one **pv**.
|
||||
|
||||
**-u STYLE, \--bar-style STYLE**
|
||||
|
||||
: Change the default progress bar style shown by "**\--progress**", or
|
||||
by the "**\--format**" sequences "**%{progress}**" or
|
||||
"**%{progress-bar-only}**", to *STYLE*. The *STYLE* can be one of
|
||||
**plain** (the default), **block**, **granular**, or **shaded**.
|
||||
These styles are described in the **FORMATTING** section below.
|
||||
|
||||
**-x SPEC, \--extra-display SPEC**
|
||||
|
||||
: As well as displaying progress to the terminal, also write it to
|
||||
*SPEC*. The *SPEC* must start with a comma-separated list of
|
||||
destinations, and can optionally be followed by a colon and a format
|
||||
string. The destinations can be **windowtitle** or **window** for
|
||||
the xterm window title, and **processtitle**, **proctitle**,
|
||||
**process**, or **proc** for the process title displayed by
|
||||
**ps**(1). If a format string is not supplied, the same format is
|
||||
used as for the terminal. For example,
|
||||
"**-x \'window,process:%t %b %r\'**" will show the elapsed time,
|
||||
bytes transferred, and rate, in both the window title and the
|
||||
process title.
|
||||
|
||||
**-9, \--conemu**
|
||||
|
||||
: As well as displaying progress to the terminal, also emit the ConEmu
|
||||
\"progress bar\" sequences (OSC 9;4) to show the progress percentage
|
||||
in the terminal\'s title tab, on terminals which support it. This is
|
||||
equivalent to adding "%{progress-conemu}" to the **\--format**
|
||||
string.
|
||||
|
||||
**-v, \--stats**
|
||||
|
||||
: At the end of the transfer, write an additional line showing the
|
||||
transfer rate minimum, mean, maximum, and standard deviation. The
|
||||
values are always in bytes per second (or bits, with "**\--bits**").
|
||||
|
||||
**-f, \--force**
|
||||
|
||||
: Force output. Normally, **pv** will not output any visual display if
|
||||
standard error is not a terminal. This option forces it to do so.
|
||||
|
||||
**-c, \--cursor**
|
||||
|
||||
: Use cursor positioning escape sequences to move to the initial
|
||||
terminal row when updating the display, instead of only using
|
||||
carriage returns. This allows multiple **pv** instances to show
|
||||
progress on the same terminal together.
|
||||
|
||||
For example:
|
||||
|
||||
pv --cursor --name input file.gz | gzip -d | pv --cursor --name output > file
|
||||
|
||||
As the example shows, this is often used with "**\--name**".
|
||||
|
||||
## Data transfer modifiers
|
||||
|
||||
**-o FILE, \--output FILE**
|
||||
|
||||
: Write data to *FILE* instead of standard output. If the file already
|
||||
exists, it will be truncated.
|
||||
|
||||
**-L RATE, \--rate-limit RATE**
|
||||
|
||||
: Limit the transfer to a maximum of *RATE* bytes per second. The same
|
||||
suffixes as "**\--size**" can be used. Decimal values are allowed.
|
||||
Specifying 0 will turn off rate limiting, which is useful with
|
||||
"**\--remote**".
|
||||
|
||||
**-B BYTES, \--buffer-size BYTES**
|
||||
|
||||
: Use a transfer buffer size of *BYTES* bytes. The same suffixes as
|
||||
"**\--size**" can be used. The default buffer size is the block size
|
||||
of the input file\'s filesystem multiplied by 32 (512KiB max), or
|
||||
400KiB if the block size cannot be determined. This can be useful on
|
||||
platforms like macOS with pipelines that perform better with
|
||||
specific buffer sizes such as 1024. Implies "**\--no-splice**".
|
||||
|
||||
**-C, \--no-splice**
|
||||
|
||||
: Prevent the use of **splice**(2) and **copy_file_range**(2), which
|
||||
are normally used on systems that support it to improve efficiency
|
||||
by eliminating the need for a transfer buffer.
|
||||
|
||||
In the default case that **splice**(2) or **copy_file_range**(2) are
|
||||
used, the lack of a transfer buffer prevents "**\--buffer-percent**"
|
||||
and "**\--last-written**" from working and makes
|
||||
"**\--buffer-size**" redundant, so using any of those options
|
||||
automatically switches on "**\--no-splice**".
|
||||
|
||||
Sparse files cannot be written with **splice**(2) or
|
||||
**copy_file_range**(2), so using "**\--sparse**" automatically
|
||||
switches on "**\--no-splice**".
|
||||
|
||||
Switching on "**\--no-splice**" results in a small loss of transfer
|
||||
efficiency. It has no effect on systems where **splice**(2) and
|
||||
**copy_file_range**(2) are unavailable.
|
||||
|
||||
**-J BYTES, \--pipe-buffer-size BYTES**
|
||||
|
||||
: Attempt to set the size of the output pipe buffer, and the
|
||||
intermediate input pipe buffer if one is needed, to *BYTES* bytes.
|
||||
This will silently do nothing if the requested size cannot be
|
||||
achieved. If this option is not specified, and both the output and
|
||||
the first input are pipes, then the output pipe buffer size will
|
||||
automatically be increased to match the input pipe buffer, if it was
|
||||
smaller.
|
||||
|
||||
**-E, \--skip-errors**
|
||||
|
||||
: Ignore read errors by attempting to skip past the offending
|
||||
sections. The corresponding parts of the output will be null bytes.
|
||||
At first only a few bytes will be skipped, but if there are many
|
||||
errors in a row then the skips will move up to chunks of 512. This
|
||||
is intended to be similar to "*dd conv=sync,noerror*".
|
||||
|
||||
Specify "**\--skip-errors**" twice to only report a read error once
|
||||
per file, instead of reporting each byte range skipped.
|
||||
|
||||
**-Z BYTES, \--error-skip-block BYTES**
|
||||
|
||||
: When ignoring read errors with "**\--skip-errors**", instead of
|
||||
trying to adaptively skip by reading small amounts and skipping
|
||||
progressively larger sections until a read succeeds, move to the
|
||||
next file block of *BYTES* bytes as soon as an error occurs. There
|
||||
may still be some shorter skips where the block being skipped
|
||||
coincides with the end of the transfer buffer. The same suffixes as
|
||||
"**\--size**" can be used.
|
||||
|
||||
This option can only be used with "**\--skip-errors**" and is
|
||||
intended for use when reading from a block device, such as
|
||||
"**\--skip-errors \--error-skip-block 4K**" to skip in 4 kibibyte
|
||||
blocks. This will speed up reads from faulty media, at the expense
|
||||
of potentially losing more data.
|
||||
|
||||
**-S, \--stop-at-size**
|
||||
|
||||
: If a size was specified with "**\--size**", stop transferring data
|
||||
once that many bytes have been written, instead of continuing to the
|
||||
end of input.
|
||||
|
||||
**-Y, \--sync**
|
||||
|
||||
: After every write operation, synchronise the buffer caches to disk
|
||||
with **sync**(2), or **fdatasync**(2) if possible. This has no
|
||||
effect when the output is a pipe. Using "**\--sync**" may improve
|
||||
the accuracy of the progress bar when writing to a slow disk.
|
||||
|
||||
**-K, \--direct-io**
|
||||
|
||||
: Set the **O_DIRECT** flag on all inputs and outputs, if it is
|
||||
available. This will minimise the effect of caches, at the cost of
|
||||
performance. Due to memory alignment requirements, it also may cause
|
||||
read or write failures with an error of "Invalid argument",
|
||||
especially if reading and writing files across a variety of
|
||||
filesystems in a single **pv** call. Use this option with caution.
|
||||
|
||||
**-O, \--sparse**
|
||||
|
||||
: When writing null bytes, try to seek, producing a sparse output
|
||||
file. Implies "**\--no-splice**". On filesystems without sparse file
|
||||
support, or when the output is not seekable, this option will have
|
||||
no effect other than to turn on "**\--no-splice**".
|
||||
|
||||
**-X, \--discard**
|
||||
|
||||
: Instead of transferring input data to standard output, discard it.
|
||||
This is equivalent to redirecting standard output to */dev/null*,
|
||||
except that **write**(2) is never called.
|
||||
|
||||
**-U FILE, \--store-and-forward FILE**
|
||||
|
||||
: Instead of passing data through immediately, do it in two stages -
|
||||
first read all input and write it to *FILE*, and then once the input
|
||||
is exhausted, read all of *FILE* and write it to the output. *FILE*
|
||||
remains in place afterwards, unless it is "**-**", in which case
|
||||
**pv** creates a temporary file for this purpose, and automatically
|
||||
removes it afterwards.
|
||||
|
||||
A common use for this is this where one part of a pipeline generates
|
||||
data quickly but of unknown size, and the next part processes it
|
||||
slowly. With "*quick* **\| pv -U - \|** *slow*", a progress bar is
|
||||
displayed with unknown size for the *quick* part, then a second is
|
||||
shown with a known size and ETA for the *slow* part.
|
||||
|
||||
## Alternative operating modes
|
||||
|
||||
**-d**, **\--watchfd** *PID*\[:*FD*\]\|=*NAME*\|@*LISTFILE*\...
|
||||
|
||||
: Instead of transferring data, watch file descriptor *FD* of process
|
||||
*PID*, and show its progress. Other data transfer modifiers - and
|
||||
remote control - may not be used with this option.
|
||||
|
||||
If a *PID* is specified without an *FD*, then that process will be
|
||||
watched, and all regular files and block devices it opens will be
|
||||
shown with a progress bar.
|
||||
|
||||
If a *NAME* is specified, prefixed with \"=\", then processes with
|
||||
that name will be found with **pgrep**(1), and as watched described
|
||||
above.
|
||||
|
||||
If a *LISTFILE* is specified, prefixed with \"@\", the lines in that
|
||||
file will be used as additional arguments.
|
||||
|
||||
All remaining non-option arguments will also be treated as
|
||||
additional arguments.
|
||||
|
||||
The **pv** process will exit when all *FD*s have either changed to a
|
||||
different file, changed read/write mode, or have closed, and all
|
||||
*PID*s (without a specific *FD*) have exited.
|
||||
|
||||
**-R PID, \--remote PID**
|
||||
|
||||
: Remotely control another instance of **pv** with process ID *PID*,
|
||||
making it act as though it had been given this instance\'s command
|
||||
line. For example, if "**pv \--rate-limit 123K**" is running with
|
||||
process ID 9876, then running
|
||||
"**pv \--remote 9876 \--rate-limit 321K**" will cause process 9876
|
||||
to start using a rate limit of 321KiB instead of 123KiB. Note that
|
||||
some options cannot be changed while running, such as
|
||||
"**\--cursor**", "**\--line-mode**", "**\--force**",
|
||||
"**\--delay-start**", "**\--skip-errors**", and
|
||||
"**\--stop-at-size**".
|
||||
|
||||
**-Q PID, \--query PID**
|
||||
|
||||
: Display the transfer progress of another instance of **pv** with
|
||||
process ID *PID*, owned by the same user.
|
||||
|
||||
Some output modifiers can only be used while querying another
|
||||
process if they match those of that process - such as
|
||||
"**\--line-mode**", "**\--null**", and "**\--average-rate-window**".
|
||||
Data transfer modifiers will have no effect.
|
||||
|
||||
**-M** *SIDE*, **\--monitor** *SIDE*
|
||||
|
||||
: Run the command specified by the remaining arguments, and monitor
|
||||
its standard input, its standard output, or both, depending on
|
||||
whether *SIDE* is "**in**", "**out**", or "**both**". Use "**\--**"
|
||||
after all of the **pv** options to keep the monitored command\'s
|
||||
options separate.
|
||||
|
||||
With a *SIDE* of "**both**", two progress bars will be shown. All of
|
||||
**pv**\'s display switches, output modifiers, and data transfer
|
||||
modifiers will apply to both sides.
|
||||
|
||||
For example, "**pv \--cursor \--monitor both \-- gzip -9**" is
|
||||
equivalent to "**pv \--cursor \| gzip -9 \| pv \--cursor**", except
|
||||
that the latter can\'t show the input:output ratio.
|
||||
|
||||
The "**\--format**" and "**\--name**" options may be specified
|
||||
twice, in which case the first one applies to the input side and the
|
||||
second applies to the output side. If no "**\--format**" options are
|
||||
specified, the default format based on the other display switches is
|
||||
used as normal, except that the ratio is added to the output side
|
||||
when *SIDE* is "**both**".
|
||||
|
||||
The values "**0**", "**1**", and "**2**" may be used as synonyms for
|
||||
"**in**", "**out**", and "**both**".
|
||||
|
||||
This option cannot be used with "**\--store-and-forward".**
|
||||
|
||||
## Other options
|
||||
|
||||
**-P FILE, \--pidfile FILE**
|
||||
|
||||
: Save the process ID of **pv** in *FILE*. The file will be replaced
|
||||
if it already exists, and will be removed when **pv** exits. While
|
||||
**pv** is running, *FILE* will contain a single number - the process
|
||||
ID of **pv** - followed by a newline.
|
||||
|
||||
**-h, \--help**
|
||||
|
||||
: Print a usage message on standard output and exit successfully.
|
||||
|
||||
**-V, \--version**
|
||||
|
||||
: Print version information on standard output and exit successfully.
|
||||
|
||||
# FORMATTING
|
||||
|
||||
Format strings used by "**\--format**" and "**\--extra-display**" can
|
||||
contain the following sequences:
|
||||
|
||||
**%p**, **%{progress}**
|
||||
|
||||
: Progress bar (suffixed with a percentage if the size is known).
|
||||
Equivalent to "**\--progress**". Expands to fill the remaining space
|
||||
unless prefixed by a number to set the width, such as "**%20p**" or
|
||||
"**%20{progress}**".
|
||||
|
||||
**%{progress-bar-only}**
|
||||
|
||||
: Progress bar, without any sides, and without any percentage
|
||||
displayed afterwards. Expands to fill the remaining space unless
|
||||
prefixed by a number.
|
||||
|
||||
**%{progress-amount-only}**
|
||||
|
||||
: The percentage completion (or maximum rate, with "**\--gauge**" when
|
||||
the size is unknown).
|
||||
|
||||
**%{progress-conemu}**
|
||||
|
||||
: Emit the ConEmu \"progress bar\" sequences (OSC 9;4) to show the
|
||||
progress percentage in the terminal\'s title tab, on terminals which
|
||||
support it.
|
||||
|
||||
**%{bar-plain}**
|
||||
|
||||
: Progress bar in the standard plain format, without any sides, and
|
||||
without any percentage displayed afterwards. Expands to fill the
|
||||
remaining space unless prefixed by a number.
|
||||
|
||||
**%{bar-block}**
|
||||
|
||||
: Progress bar using Unicode full blocks, without any sides, and
|
||||
without any percentage displayed afterwards. Expands to fill the
|
||||
remaining space unless prefixed by a number. If UTF-8 output is not
|
||||
available, the plain format is used.
|
||||
|
||||
**%{bar-granular}**
|
||||
|
||||
: Progress bar using Unicode full blocks, and 1/8th blocks for partial
|
||||
fills, providing a more granular display. Like the other "%{bar}"
|
||||
strings this shows the bar without any sides, and without any
|
||||
percentage displayed afterwards, and expands to fill the remaining
|
||||
space unless prefixed by a number. If UTF-8 output is not available,
|
||||
the plain format is used.
|
||||
|
||||
**%{bar-shaded}**
|
||||
|
||||
: Progress bar using Unicode full blocks and shade characters - dark
|
||||
and medium shade are used for partial fills, and the light shade is
|
||||
used for the background. Like the other "%{bar}" strings this shows
|
||||
the bar without any sides, and without any percentage displayed
|
||||
afterwards, and expands to fill the remaining space unless prefixed
|
||||
by a number. If UTF-8 output is not available, the plain format is
|
||||
used.
|
||||
|
||||
**%t**, **%{timer}**
|
||||
|
||||
: Elapsed time. Equivalent to "**\--timer**".
|
||||
|
||||
**%e**, **%{eta}**
|
||||
|
||||
: ETA as time remaining. Equivalent to "**\--eta**".
|
||||
|
||||
**%I**, **%{fineta}**
|
||||
|
||||
: ETA as local time at which the transfer will finish. Equivalent to
|
||||
"**\--fineta**".
|
||||
|
||||
**%r**, **%{rate}**
|
||||
|
||||
: Current data transfer rate. Equivalent to "**\--rate**".
|
||||
|
||||
**%a**, **%{average-rate}**
|
||||
|
||||
: Average data transfer rate. Equivalent to "**\--average-rate**".
|
||||
|
||||
**%b**, **%{bytes}**, **%{transferred}**
|
||||
|
||||
: Bytes transferred so far (or lines if "**\--line-mode**" was
|
||||
specified). Equivalent to "**\--bytes**". If "**\--bits**" was
|
||||
specified, "**%b**" shows the bits transferred so far, not bytes.
|
||||
|
||||
**%{ratio}**
|
||||
|
||||
: Show the ratio of bytes transferred by the other side to the bytes
|
||||
transferred by this side, in "**\--monitor both**" mode.
|
||||
|
||||
**%T**, **%{buffer-percent}**
|
||||
|
||||
: Percentage of the transfer buffer in use. Equivalent to
|
||||
"**\--buffer-percent**", but using it does not turn on
|
||||
"**\--no-splice**".
|
||||
|
||||
If the transfer is using **splice**(2), displays "{\-\-\--}"; if the
|
||||
transfer is using **splice**(2) via an intermediate input pipe,
|
||||
displays "{-\|\|-}"; and if the transfer is using
|
||||
**copy_file_range**(2), displays "{\-\--\>}".
|
||||
|
||||
**%nA**, **%n{last-written}**
|
||||
|
||||
: Show the last *n* bytes written (for example, "**%16A**" shows the
|
||||
last 16 bytes). Shows only dots if the transfer is using
|
||||
**splice**(2) or **copy_file_range**(2), since these transfer modes
|
||||
do not use the buffer.
|
||||
|
||||
**%nL**, **%n{previous-line}**
|
||||
|
||||
: Show the first *n* bytes of the most recently written line (for
|
||||
example, "**%40L**" shows the first 40 bytes). If no *n* is given,
|
||||
then this expands to fill the available space. Shows only spaces if
|
||||
the transfer is using **splice**(2) or **copy_file_range**(2).
|
||||
|
||||
**%N**, **%{name}**
|
||||
|
||||
: Show the name prefix given by "**\--name**". Padded to 9 characters
|
||||
with spaces, and suffixed with ":".
|
||||
|
||||
**%{sgr:colour,\...}**
|
||||
|
||||
: Emit ECMA-48 SGR (Select Graphic Rendition) codes if the terminal
|
||||
supports colours, where *colour,\...* is a comma-separated list of
|
||||
any of the keywords below, or the numeric values from
|
||||
**console_codes**(4). If colour support is not available, nothing is
|
||||
emitted.
|
||||
|
||||
Supported keywords are: **reset** or **none**, **black**, **red**,
|
||||
**green**, **brown** or **yellow**, **blue**, **magenta**, **cyan**,
|
||||
**white**, **fg-black**, **fg-red**, **fg-green**, **fg-brown** or
|
||||
**fg-yellow**, **fg-blue**, **fg-magenta**, **fg-cyan**,
|
||||
**fg-white**, **fg-default**, **bg-black**, **bg-red**,
|
||||
**bg-green**, **bg-brown** or **bg-yellow**, **bg-blue**,
|
||||
**bg-magenta**, **bg-cyan**, **bg-white**, **bg-default**, **bold**,
|
||||
**dim**, **italic**, **underscore** or **underline**, **blink**,
|
||||
**reverse**, **no-bold** or **no-dim**, **no-italic**,
|
||||
**no-underscore** or **no-underline**, **no-blink**, **no-reverse**.
|
||||
|
||||
With colours, the optional \"fg-\" prefix indicates foreground; a
|
||||
prefix of \"bg-\" indicates background.
|
||||
|
||||
For example, "**%{sgr:green,bold}TEXT%{sgr:reset}**" will make
|
||||
*TEXT* bold green on supported terminals.
|
||||
|
||||
**%%**
|
||||
|
||||
: A single "%".
|
||||
|
||||
Any other contents are reproduced in the progress display as-is.
|
||||
|
||||
The format string equivalent of the default display switches is
|
||||
"**%b %t %r %p %e**".
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
Some suggested common switch combinations:
|
||||
|
||||
**pv -ptebar**
|
||||
|
||||
: Show a progress bar, elapsed time, estimated completion time, byte
|
||||
counter, average rate, and current rate.
|
||||
|
||||
**pv -betlap**
|
||||
|
||||
: Show a progress bar, elapsed time, estimated completion time, line
|
||||
counter, and average rate, counting lines instead of bytes.
|
||||
|
||||
**pv -btrpg**
|
||||
|
||||
: Show the amount transferred, elapsed time, current rate, and a gauge
|
||||
showing the current rate as a percentage of the maximum rate seen -
|
||||
useful in a pipeline where the total size is unknown. (If the size
|
||||
*is* known, these options will show the percentage completion
|
||||
instead of the rate gauge).
|
||||
|
||||
**pv -t**
|
||||
|
||||
: Show only the elapsed time - useful as a simple timer, such as
|
||||
"**sleep 10m \| pv -t**".
|
||||
|
||||
**pv -pterb**
|
||||
|
||||
: The default behaviour: progress bar, elapsed time, estimated
|
||||
completion time, current rate, and byte counter.
|
||||
|
||||
**pv \--format=\'%{progress-conemu}%{bytes} %{timer} %{rate} %{progress} %{eta}\'**
|
||||
|
||||
: Show the byte counter, elapsed time, current rate, progress bar, and
|
||||
ETA, and show the percentage progress in the terminal\'s tab bar, on
|
||||
terminals that support ConEmu OSC 9;4 sequences.
|
||||
|
||||
On macOS, it may be useful to specify "**\--buffer-size 1024**" in a
|
||||
pipeline, as this may improve performance.
|
||||
|
||||
To watch how quickly a file is transferred using **nc**(1):
|
||||
|
||||
pv file | nc -w 1 somewhere.com 3000
|
||||
|
||||
A similar example, transferring a file from another process and passing
|
||||
the expected size to **pv**:
|
||||
|
||||
cat file | pv --size 12345 | nc -w 1 somewhere.com 3000
|
||||
|
||||
To watch the progress of creating a tar.gz archive:
|
||||
|
||||
tar cf - directory/ \
|
||||
| pv --size $(du -sb directory/ | awk '{print $1}') \
|
||||
| gzip -9 \
|
||||
> out.tar.gz
|
||||
|
||||
An alternative way of doing the same thing:
|
||||
|
||||
tar cf - directory/ \
|
||||
| pv --size @directory/ \
|
||||
| gzip -9 \
|
||||
> out.tar.gz
|
||||
|
||||
Taking an image of a disk, skipping errors:
|
||||
|
||||
pv -EE /dev/your/disk/device > disk-image.img
|
||||
|
||||
Writing an image back to a disk:
|
||||
|
||||
pv disk-image.img > /dev/your/disk/device
|
||||
|
||||
Zeroing a disk:
|
||||
|
||||
pv < /dev/zero > /dev/your/disk/device
|
||||
|
||||
Note that if the input size cannot be calculated, and the output is a
|
||||
block device, then the size of the block device will be used and **pv**
|
||||
will automatically stop at that size as if "**\--stop-at-size**" had
|
||||
been given.
|
||||
|
||||
(Linux and macOS only): Watching file descriptor 3 opened by another
|
||||
process 1234:
|
||||
|
||||
pv --watchfd 1234:3
|
||||
|
||||
(Linux and macOS only): Watching all file descriptors used by process
|
||||
1234:
|
||||
|
||||
pv --watchfd 1234
|
||||
|
||||
Rate-limiting the transfer between two processes in a pipeline, with no
|
||||
display:
|
||||
|
||||
producer | pv --quiet --rate-limit 1M | consumer
|
||||
|
||||
Sending logs to a processing script, showing the most recent line as
|
||||
part of the progress display:
|
||||
|
||||
pv --no-splice --format '%a %p : %L' big.log | processing-script
|
||||
|
||||
Showing progress as lines of JSON data:
|
||||
|
||||
pv --numeric --format '{"elapsed":%t,"bytes":%b,"rate":%r,"percentage":%{progress-amount-only}}' big.log | processing-script
|
||||
|
||||
# EXIT STATUS
|
||||
|
||||
An exit status of 1 indicates a problem with the "**\--remote**",
|
||||
"**\--query**", "**\--pidfile**", or "**\--monitor**" options.
|
||||
|
||||
Any other exit status is a bitmask of the following:
|
||||
|
||||
**2**
|
||||
|
||||
: One or more files could not be accessed, **stat**(2)ed, or opened.
|
||||
|
||||
**4**
|
||||
|
||||
: An input file was the same as the output file.
|
||||
|
||||
**8**
|
||||
|
||||
: Internal error with closing a file or moving to the next file.
|
||||
|
||||
**16**
|
||||
|
||||
: There was an error while transferring data from one or more input
|
||||
files.
|
||||
|
||||
**32**
|
||||
|
||||
: A signal was caught that caused an early exit.
|
||||
|
||||
**64**
|
||||
|
||||
: Memory allocation failed.
|
||||
|
||||
A zero exit status indicates no problems.
|
||||
|
||||
# ENVIRONMENT
|
||||
|
||||
The following environment variables may affect **pv**:
|
||||
|
||||
**HOME**
|
||||
|
||||
: The current user\'s home directory. This may be used by
|
||||
"**\--remote**" and "**\--query**" to exchange messages between
|
||||
**pv** instances: if the */run/user/UID/* directory does not exist
|
||||
(where *UID* is the current user ID), then *\$HOME/.pv/* will be
|
||||
used instead.
|
||||
|
||||
**TMPDIR**, **TMP**
|
||||
|
||||
: The directory to create per-tty lock files for the terminal when
|
||||
using "**\--cursor**". If **TMPDIR** is set to a non-empty value, it
|
||||
is the directory under which lock files are created. Otherwise,
|
||||
**TMP** is used. If neither are set, then */tmp* is used.
|
||||
|
||||
# NOTES
|
||||
|
||||
In some versions of **bash**(1) and **zsh**(1), the construct
|
||||
"**\<(pv filename)**" will not output any progress to the terminal when
|
||||
run from an interactive shell, due to the subprocess being run in a
|
||||
separate process group from the one that owns the terminal. In these
|
||||
cases, use "**\--force**".
|
||||
|
||||
If **pv** is used in a pipeline in **zsh** version 5.8, and the last
|
||||
command in the pipeline is based on shell builtins, **zsh** takes
|
||||
control of the terminal away from **pv**, preventing progress from being
|
||||
displayed. For example, this will produce no progress bar:
|
||||
|
||||
pv InputFile | { while read -r line; do sleep 0.1; done; }
|
||||
|
||||
To work around this, put the last commands of the pipeline in normal
|
||||
brackets to force the use of a subshell:
|
||||
|
||||
pv InputFile | ( while read -r line; do sleep 0.1; done; )
|
||||
|
||||
Refer to [issue #105](https://codeberg.org/ivarch/pv/issues/105) for
|
||||
full details.
|
||||
|
||||
The "**\--remote**" and "**\--query**" options require that either
|
||||
*/run/user/\<uid\>/* or *\$HOME/* can be written to, for inter-process
|
||||
communication.
|
||||
|
||||
The "**\--size**" option has no effect if used with
|
||||
"**\--watchfd** *PID*" to watch all file descriptors of a process, but
|
||||
will work with "**\--watchfd** *PID*:*FD*" to watch a single file
|
||||
descriptor.
|
||||
|
||||
If the input size cannot be calculated, and the output is a block
|
||||
device, then **pv** will read the output device\'s size, use that as if
|
||||
it had been passed to "**\--size**", and activate "**\--stop-at-size**".
|
||||
|
||||
The "**%nA**" and "**%nL**" format sequences may not be effective with
|
||||
small input files, and "**%nL**" may be a few lines out due to buffering
|
||||
within the pipeline itself.
|
||||
|
||||
Numbers passed to "**\--size**", "**\--buffer-size**",
|
||||
"**\--pipe-buffer-size**", and "**\--error-skip-block**" may all be
|
||||
expressed as decimals if followed by a suffix, so for example
|
||||
"*\--size 1.5G*" is equivalent to "*\--size 1536M*".
|
||||
|
||||
Numbers passed to "**\--rate-limit**" may be expressed as decimals with
|
||||
or without a suffix.
|
||||
|
||||
Numbers passed to "**\--interval**" and "**\--delay-start**" may be
|
||||
integers or decimals, but may not have a suffix.
|
||||
|
||||
Numbers passed to "**\--last-written**", "**\--width**",
|
||||
"**\--height**", "**\--average-rate-window**", "**\--remote**", and
|
||||
"**\--query**" must be integers with no suffix.
|
||||
|
||||
When "**\--sparse**" is in effect and output is being written to a file,
|
||||
that file may look like it has stopped growing if inspected with
|
||||
**ls**(1) while null bytes are being written, even though **pv** still
|
||||
reports progress. This is because of the way sparse output is achieved,
|
||||
and the file will be the correct size when the transfer ends.
|
||||
|
||||
# REPORTING BUGS
|
||||
|
||||
Please report bugs or feature requests via the issue tracker linked from
|
||||
the [**pv** home page](https://ivarch.com/p/pv).
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
**cat**(1), **splice**(2), **copy_file_range**(2), **fsync**(2),
|
||||
**fdatasync**(2), **open**(2) (for **O_DIRECT**), **console_codes**(4)
|
||||
|
||||
# COPYRIGHT
|
||||
|
||||
Copyright © 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew
|
||||
Wood.
|
||||
|
||||
License GPLv3+: [GNU GPL version 3 or
|
||||
later](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||
|
||||
This is free software: you are free to change and redistribute it. There
|
||||
is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
Please see the package\'s ACKNOWLEDGEMENTS file for a complete list of
|
||||
contributors.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Configuration for the foss-release.sh script.
|
||||
# The script is here: https://codeberg.org/ivarch/scripts
|
||||
|
||||
set maintainer andrew.wood@ivarch.com
|
||||
set mainprogram auto
|
||||
set version auto
|
||||
set mandir docs
|
||||
set newsdir docs
|
||||
|
||||
export SKIP_VALGRIND_TESTS=1
|
||||
|
||||
section Initial checks
|
||||
action check_po
|
||||
action check_version_news
|
||||
action check_version_autoconf
|
||||
action check_version_man
|
||||
|
||||
section Initial build
|
||||
action configure
|
||||
action make
|
||||
action check_analyse
|
||||
action check_version_program
|
||||
action check_version_year
|
||||
|
||||
section Documentation and source reformatting
|
||||
action man_md
|
||||
action man_html
|
||||
action news_html
|
||||
action make_indent
|
||||
|
||||
section Update po files
|
||||
action make_update_po
|
||||
|
||||
section Run autoreconf
|
||||
action autoreconf
|
||||
|
||||
section Commit check
|
||||
action check_git_status
|
||||
|
||||
section Release archive
|
||||
action check_make_distcheck
|
||||
action make_dist
|
||||
|
||||
section Lab tests
|
||||
action labtest
|
||||
|
||||
section Sign release
|
||||
action sign_tarball
|
||||
|
||||
section Build OS packages
|
||||
action parmo_build
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Script to autogenerate the `configure' script, and the config header
|
||||
# template if `autoconf' is available, and then rebuild the dependency list.
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
test -t 1 && echo "${0##*/}: running autoconf"
|
||||
autoconf autoconf/configure.in > configure
|
||||
chmod 755 configure
|
||||
|
||||
if command -v autoheader >/dev/null; then
|
||||
test -t 1 && echo "${0##*/}: running autoheader"
|
||||
autoheader autoconf/configure.in
|
||||
else
|
||||
test -t 1 && echo "${0##*/}: autoheader not found, skipping"
|
||||
fi
|
||||
|
||||
echo > autoconf/make/depend.mk~
|
||||
echo > autoconf/make/filelist.mk~
|
||||
echo > autoconf/make/modules.mk~
|
||||
|
||||
MAKE=make
|
||||
command -v gmake >/dev/null 2>&1 && MAKE=gmake
|
||||
|
||||
rm -rf .gen
|
||||
mkdir .gen
|
||||
cd .gen
|
||||
|
||||
test -t 1 && echo "${0##*/}: running new \`configure' script"
|
||||
sh ../configure
|
||||
|
||||
test -t 1 && echo "${0##*/}: regenerating Makefile fragments"
|
||||
$MAKE make
|
||||
$MAKE dep
|
||||
|
||||
test -t 1 && echo "${0##*/}: cleaning up"
|
||||
cd ..
|
||||
rm -rf .gen
|
||||
rm -rf autom4te.cache autoconf/autom4te.cache
|
||||
|
||||
# EOF
|
||||
@@ -0,0 +1,10 @@
|
||||
Makevars.template
|
||||
*.sed
|
||||
*.gmo
|
||||
*.header
|
||||
*.sin
|
||||
*.pot
|
||||
Rules-quot
|
||||
stamp-po
|
||||
*~
|
||||
Makefile.in.in
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
cs
|
||||
de
|
||||
fi
|
||||
fr
|
||||
it
|
||||
ka
|
||||
pl
|
||||
pt
|
||||
ro
|
||||
ru
|
||||
tr
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
# Makefile variables for PO directory in any package using GNU gettext.
|
||||
#
|
||||
# Copyright (C) 2003-2019 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to use, copy, distribute, and modify it.
|
||||
|
||||
# Usually the message domain is the same as the package name.
|
||||
DOMAIN = $(PACKAGE)
|
||||
|
||||
# These two variables depend on the location of this directory.
|
||||
subdir = po
|
||||
top_builddir = ..
|
||||
|
||||
# These options get passed to xgettext.
|
||||
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
|
||||
|
||||
# This is the copyright holder that gets inserted into the header of the
|
||||
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
|
||||
# package. (Note that the msgstr strings, extracted from the package's
|
||||
# sources, belong to the copyright holder of the package.) Translators are
|
||||
# expected to transfer the copyright for their translations to this person
|
||||
# or entity, or to disclaim their copyright. The empty string stands for
|
||||
# the public domain; in this case the translators are expected to disclaim
|
||||
# their copyright.
|
||||
COPYRIGHT_HOLDER = Andrew Wood
|
||||
|
||||
# This tells whether or not to prepend "GNU " prefix to the package
|
||||
# name that gets inserted into the header of the $(DOMAIN).pot file.
|
||||
# Possible values are "yes", "no", or empty. If it is empty, try to
|
||||
# detect it automatically by scanning the files in $(top_srcdir) for
|
||||
# "GNU packagename" string.
|
||||
PACKAGE_GNU =
|
||||
|
||||
# This is the email address or URL to which the translators shall report
|
||||
# bugs in the untranslated strings:
|
||||
# - Strings which are not entire sentences, see the maintainer guidelines
|
||||
# in the GNU gettext documentation, section 'Preparing Strings'.
|
||||
# - Strings which use unclear terms or require additional context to be
|
||||
# understood.
|
||||
# - Strings which make invalid assumptions about notation of date, time or
|
||||
# money.
|
||||
# - Pluralisation problems.
|
||||
# - Incorrect English spelling.
|
||||
# - Incorrect formatting.
|
||||
# It can be your email address, or a mailing list address where translators
|
||||
# can write to without being subscribed, or the URL of a web page through
|
||||
# which the translators can contact you.
|
||||
MSGID_BUGS_ADDRESS =
|
||||
|
||||
# This is the list of locale categories, beyond LC_MESSAGES, for which the
|
||||
# message catalogs shall be used. It is usually empty.
|
||||
EXTRA_LOCALE_CATEGORIES =
|
||||
|
||||
# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'
|
||||
# context. Possible values are "yes" and "no". Set this to yes if the
|
||||
# package uses functions taking also a message context, like pgettext(), or
|
||||
# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.
|
||||
USE_MSGCTXT = no
|
||||
|
||||
# These options get passed to msgmerge.
|
||||
# Useful options are in particular:
|
||||
# --previous to keep previous msgids of translated messages,
|
||||
# --quiet to reduce the verbosity.
|
||||
MSGMERGE_OPTIONS =
|
||||
|
||||
# These options get passed to msginit.
|
||||
# If you want to disable line wrapping when writing PO files, add
|
||||
# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and
|
||||
# MSGINIT_OPTIONS.
|
||||
MSGINIT_OPTIONS =
|
||||
|
||||
# This tells whether or not to regenerate a PO file when $(DOMAIN).pot
|
||||
# has changed. Possible values are "yes" and "no". Set this to no if
|
||||
# the POT file is checked in the repository and the version control
|
||||
# program ignores timestamps.
|
||||
PO_DEPENDS_ON_POT = yes
|
||||
|
||||
# This tells whether or not to forcibly update $(DOMAIN).pot and
|
||||
# regenerate PO files on "make dist". Possible values are "yes" and
|
||||
# "no". Set this to no if the POT file and PO files are maintained
|
||||
# externally.
|
||||
DIST_DEPENDS_ON_UPDATE_PO = yes
|
||||
@@ -0,0 +1,33 @@
|
||||
src/main/debug.c
|
||||
src/main/help.c
|
||||
src/main/main.c
|
||||
src/main/options.c
|
||||
src/main/version.c
|
||||
src/pv/calc.c
|
||||
src/pv/cursor.c
|
||||
src/pv/display.c
|
||||
src/pv/elapsedtime.c
|
||||
src/pv/file.c
|
||||
src/pv/format/averagerate.c
|
||||
src/pv/format/barstyle.c
|
||||
src/pv/format/bufferpercent.c
|
||||
src/pv/format/bytes.c
|
||||
src/pv/format/eta.c
|
||||
src/pv/format/fineta.c
|
||||
src/pv/format/lastwritten.c
|
||||
src/pv/format/name.c
|
||||
src/pv/format/previousline.c
|
||||
src/pv/format/progressbar.c
|
||||
src/pv/format/rate.c
|
||||
src/pv/format/ratio.c
|
||||
src/pv/format/sgr.c
|
||||
src/pv/format/timer.c
|
||||
src/pv/loop.c
|
||||
src/pv/number.c
|
||||
src/pv/proctitle.c
|
||||
src/pv/remote.c
|
||||
src/pv/signal.c
|
||||
src/pv/state.c
|
||||
src/pv/string.c
|
||||
src/pv/transfer.c
|
||||
src/pv/watchpid.c
|
||||
@@ -0,0 +1,613 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2024-10-13 20:43+0000\n"
|
||||
"Last-Translator: mmatous <mmatous@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: Czech <https://translate.codeberg.org/projects/pv/pv/cs/>\n"
|
||||
"Language: cs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 5.7.2\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "ukaž indikátor průběhu"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "ukaž uběhlý čas"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "ukaž přibližný zbývající čas"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "ukaž přibližný čas dokončení"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "ukaž okamžitou rychlost přenosu dat"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "ukaž průměrnou rychlost přenosu dat"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "ukaž počet přenesených bajtů"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "ukaž procento využité vyrovnávací paměti"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "ČÍS"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "zobraz ČÍS posledních zapsaných bajtů"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMÁT"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "nastav formát výstupu na FORMÁT"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "vypisuj procenta, ne vizuální informace"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "nevypisuj žádné informace o přenosu"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "ukaž počet přenesených bitů"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "zacházej se suffixy jako s násobky 1000 namísto 1024"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "nic nevypisuj, dokud není přenesen první byte"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "SEK"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "nic nevypisuj, dokud neuplyne SEK sekund"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "VEL"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "nastav očekávanou velikost dat na VEL bajtů"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "pokud je velikost neznámá, ukaž rychlost vs maximální rychlost"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "počítej řádky místo bajtů"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "řádky jsou zakončené nulovým znakem"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualizuj každých SEK sekund"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "počítej průměrnou rychlost za posledních SEK sekund (výchozí: 30)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "ŠÍŘ"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "předpokládej šířku terminálu ŠÍŘ znaků"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "VÝŠ"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "předpokládej výšku terminálu VÝŠ znaků"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "JMÉNO"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "přidej JMÉNO před vizuální informace"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "po dokončení vypiš údaje o přenosu"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "vypisuj výstup i pokud standardní chybový výstup není terminál"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "pozicuj kurzor pomocí řídících znaků"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "SOUBOR"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "zapiš výstup do SOUBORu namísto standardního výstupu"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "RYCH"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "omez přenosovou rychlost na RYCH bajtů za sekundu"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "BAJT"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "použij vyrovnávací pamět BAJT bajtů"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nepoužívej splice(), vždy použij read/write"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignoruj chyby při čtení vstupu"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "přeskakuj chyby v blocích BAJTů naráz"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "zastav po přenosu --size bajtů"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "po každém zápisu vyprázdni cache na disk"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "použij přímý V/V k obejítí cache"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "zahoď vstup namísto zápisu na výstup"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "zapiš veškerý vstup do SOUBORu před výpisem na výstup"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "sleduj soubor DS otevřený procesem PID"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "aktualizuj nastavení procesu PID"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "ulož id procesu do SOUBORu"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "ukaž pomoc a skonči"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "ukaž informace o verzi a skonči"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "zapiš ladící záznamy do SOUBORu"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Použití: %s [VOLBY] [SOUBOR]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Spoj SOUBOR(y) nebo standardní vstup na standardního výstup, s monitoringem."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Prosím, hlašte veškeré chyby na: %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(vstup)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "chyba přidělování paměti"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "očekáváno ID procesu nebo dvojice PID:DS"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "neplatné ID procesu"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "očekáván celočíselný argument"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "očekáván číselný argument"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Zkuste `%s --help' pro více informací."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Zkuste `%s --h' pro více informací."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"při sledování deskriptorů souborů nelze použít řádkový mód nebo volby pro "
|
||||
"modifikaci přenosu"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr "při sledování deskriptorů souborů nelze pozicování kurzoru použít"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "při sledování deskriptorů souborů nelze použít vzdálené ovládání"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "při sledování deskriptorů souborů nelze použít přenos souborů"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "není dostupné na systémech bez /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Licence: GPLv3+ <https://jxself.org/translations/gpl-3.cz.shtml>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr "Toto je svobodný software; můžete ho volně měnit a šířit."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Na program se nevztahuje ŽÁDNÁ ZÁRUKA, v míře povolené zákonem."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Stránka projektu"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "selhalo otevření zámkového souboru"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "přerušeno signálem"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "chyba při zavírání souboru"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "vstupní soubor je rovněž výstupem"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(žádný)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "rychlost min/avg/max/std"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "rychlost neměřena"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr "ds"
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "zpráva nepřijata"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO není na tomto systému podporováno"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "varování: detekovány chyby při čtení"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "chyba přeskočena"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "chyba při zápisu"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "není obyčejný soubor nebo blokové zařízení"
|
||||
|
||||
#~ msgid "state allocation failed"
|
||||
#~ msgstr "selhala alokace stavu"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "nebylo možné zjistit informace o souboru"
|
||||
|
||||
#~ msgid "is a directory"
|
||||
#~ msgstr "je adresář"
|
||||
|
||||
#~ msgid "failed to generate sysfs filename"
|
||||
#~ msgstr "selhalo vytváření jména pro soubor v sysfs"
|
||||
|
||||
#~ msgid "failed to read sysfs size file"
|
||||
#~ msgstr "selhalo čtení velikosti souboru v sysfs"
|
||||
|
||||
#~ msgid "failed to open block device"
|
||||
#~ msgstr "selhalo otevření blokového zařízení"
|
||||
|
||||
#~ msgid "failed to determine size of block device"
|
||||
#~ msgstr "selhalo zjištění velikosti blokového zařízení"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "selhala alokace struktury pro volby"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "selhala alokace struktury pro argv"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "selhalo zjištění názvu terminálu"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "selhal pokus o uzamčení"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "selhalo otevření terminálu"
|
||||
|
||||
#~ msgid "failed to seek to start of output"
|
||||
#~ msgstr "selhalo posunutí za začátek výstupu"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "selhalo čtení ze souboru"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "selhalo zjištění informací o výstupním souboru"
|
||||
|
||||
#~ msgid "history structure allocation failed"
|
||||
#~ msgstr "selhala alokace struktury historie"
|
||||
|
||||
#~ msgid "file list allocation failed"
|
||||
#~ msgstr "selhala alokace seznamu souborů"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "čtení selhalo"
|
||||
|
||||
#~ msgid "file is not seekable"
|
||||
#~ msgstr "souborem nelze procházet"
|
||||
|
||||
#~ msgid "failed to seek past error"
|
||||
#~ msgstr "selhal skok za chybu"
|
||||
|
||||
#~ msgid "no transfer buffer allocated"
|
||||
#~ msgstr "vyrovnávací paměť není alokována"
|
||||
|
||||
#~ msgid "failed to set interval timer"
|
||||
#~ msgstr "selhalo nastavení intervalového časovače"
|
||||
|
||||
#~ msgid "failed to clear interval timer"
|
||||
#~ msgstr "selhalo vynulování intervalového časovače"
|
||||
|
||||
#~ msgid "line position buffer allocation failed"
|
||||
#~ msgstr "selhala alokace vyrovnávací paměti pro pozici v řádcích"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "selhalo volání select"
|
||||
|
||||
#~ msgid "PID[:FD]"
|
||||
#~ msgstr "PID[:DS]"
|
||||
@@ -0,0 +1,642 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2026-08-01 18:32+0000\n"
|
||||
"Last-Translator: a-j-wood <a-j-wood@noreply.codeberg.org>\n"
|
||||
"Language-Team: German <https://translate.codeberg.org/projects/pv/pv/de/>\n"
|
||||
"Language: de\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2026.7.1\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
"From: Andrew Wood <ivarch@ubik>\n"
|
||||
"Xgettext-Options: --default-domain=pkgbuild --directory=./.pkgdir --add-"
|
||||
"comments --keyword=_ --keyword=N_\n"
|
||||
"Files: src/getopt/getopt.c src/getopt/getopt1.c src/version.c src/main/"
|
||||
"init.c src/main/help.c src/main/xpmptr.c src/guts/load.c src/guts/stop.c src/"
|
||||
"guts/configure.c src/guts/make.c src/guts/install.c src/guts/prefs.c src/ui/"
|
||||
"generate.c src/ui/main.c src/ui/xpm.c src/ui/status.c src/ui/activate.c src/"
|
||||
"ui/handlers/main.c src/ui/handlers/package.c src/ui/handlers/prefs.c src/ui/"
|
||||
"handlers/dirsel.c src/ui/handlers/popup.c src/ui/handlers/help.c src/ui/"
|
||||
"textout.c src/ui/report.c src/ui/callback.c src/nls/intl/bindtextdom.c src/"
|
||||
"nls/intl/dcgettext.c src/nls/intl/dgettext.c src/nls/intl/finddomain.c src/"
|
||||
"nls/intl/gettext.c src/nls/intl/loadmsgcat.c src/nls/intl/localealias.c src/"
|
||||
"nls/intl/textdomain.c src/nls/intl-cat/cat-compat.c src/nls/intl-gett/intl-"
|
||||
"compat.c\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "Fortschritts-Anzeige"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "zeige die verstrichene Zeit an"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "zeige die erwartete Zeit bis zum Ende an"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "zeige die absolute geschätzte Zeit bis zur Fertigstellung"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "zeige die Datentransferrate an"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "zeige die durchschnittliche Übertragungsrate"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "zeige die Anzahl der übertragenen Bytes"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "zeige, wie viel Prozent des Übertragungsbuffers in Benutzung sind"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "NUM zeige die zuletzt geschriebenen NUM Bytes"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "setze das Ausgabeformat auf FORMAT"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "Ausgabe von Prozent-Angaben statt visueller Darstellung"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "sämtliche Transferinformationen unterdrücken"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "zeige die Anzahl der übertragenen Bits"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "behandle Endungen als Vielfache von 1000 statt von 1024"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "keine Ausgabe bevor das erste Byte übertragen wurde"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "SEK"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "nichts anzeigen ehe SEK Sekunden vergangen sind"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "GRÖẞE"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "setze erwartete Datenlänge auf SIZE Byte"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "zeige Rate vs maximale Rate, falls die größe unbekannt ist"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "zähle Zeilen anstelle von Bytes"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "Zeilen sind nullterminiert"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualisiere Ausgabe nach SEK Sekunden Intervall"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
"berechne die durchschnittliche Übertragungsrate über die letzten SEK "
|
||||
"Sekunden (Standard 30s)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "BREITE"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "setze Terminal-Breite auf BREITE Zeichen"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "HÖHE"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "setze Terminal-Höhe auf HÖHE Zeichen"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "NAME"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "setze den NAMEn für visuelle Darstellung"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "STIL"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "setze die voreingestellte Darstellung auf STIL"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr "SPEC"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "Fortschritt auch an SPEC senden"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr "aktualisieren Sie den Terminal-Fortschrittszustand mit OSC 9;4 (ConEmu)"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "Übertragungsstatistiken am Ende ausgeben"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
"Ausgabe auch dann erzwingen, wenn der Fehlerausgabe-Kanal kein Terminal ist"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "benutze Escape-Sequenzen zur Cursor-Positionierung"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "DATEI"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "schreibe die Ausgabe in DATEI statt in die Standardausgabe"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "RATE"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "beschränke die Transferrate auf RATE Byte pro Sekunde"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "BYTES"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "benutze einen Puffer in der Größe von BYTES"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "anstelle von splice() immer read/write benutzen"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr "benutze einen Pipe-Puffer in der Größe von BYTES"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "Lesefehler in der Eingabe nicht beachten"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "bei Fehlern BYTES am Stück überspringen"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "anhalten, nachdem --size Bytes übertragen wurden"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "schreibe den Cache nach jedem Schreibvorgang auf die Festplatte"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "verwende direkte E/A, um den Cache zu umgehen"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr "ausgabelöcher anstelle von Nullbytes"
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "verwirf die Eingabe anstatt in die Ausgabe zu schreiben"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "Ausgabe nach FILE schrieben bevor sie ausgegeben wird"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr "PID[:FD]|=NAME|@LISTENDATEI"
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "die vom Prozess PID geöffnete Datei FD beobachten"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "Einstellungen der Prozess-PID updaten"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr "den Fortschritt des PID-Prozesses darstellen"
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
"Ein Programm ausführen und dessen Standardeingabe, -ausgabe oder beides "
|
||||
"überwachen"
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "Prozess-ID in DATEI speichern"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "zeige diese Hilfe und beende"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "zeige Versionsinformationen und beende"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "schreibe Debug-Protokolle in DATEI"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Aufruf: %s [OPTION] [DATEI]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Verbindet DATEI(en) oder den Standard-Eingabe-Kanal mit dem Standard-Ausgabe-"
|
||||
"Kanal und misst den Datenstrom."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "unterstützte Formate:"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Bitte senden Sie Fehlerberichte an %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(eingabe)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr "es muss ein auszuführendes Programm angegeben werden"
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "Fehler bei der Speicheranforderung"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr "Listendateien dürfen keine „@“-Zeilen enthalten"
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "Prozess-ID oder PID:FD-Paar erwartet"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "ungültige Prozess-ID"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr "numerischen Wert nicht verstanden"
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "Ganzzahliges Argument erwartet"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "numerisches Argument erwartet"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr "fehlender Dateiname"
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr "fehlender Prozessname"
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr "ungültige Seitenspezifikation"
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "„%s --help“ zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "„%s -h“ zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren können keine Optionen für den "
|
||||
"Zeilenmodus oder den Übertragungsmodifikator verwendet werden"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren kann Cursor-Positionierung nicht "
|
||||
"verwendet werden"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren kann die Fernbedienung nicht verwenden "
|
||||
"werden"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
"Remote-Abfragen können beim Überwachen von Dateideskriptoren nicht verwendet "
|
||||
"werden"
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren können Dateien nicht übertragen werden"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "Nicht verfügbar auf Systemen ohne /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
"Fernsteuerung und Fernabfrage können nicht gleichzeitig verwendet werden"
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr "Der Monitormodus kann mit dieser Option nicht angegeben werden"
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
"Der Monitormodus kann nicht mit Speichern-und-Weiterleiten verwendet werden"
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr "mit dieser Option können keine Dateien angegeben werden"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Lizenz: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr "Dies ist freie Software: Sie dürfen sie verändern und weiterverteilen."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Es besteht KEINE GARANTIE, soweit dies gesetzlich zulässig ist."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Projekt-Website"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "konnte Sperrdatei nicht öffnen"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "von einem Signal unterbrochen"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnµm kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnµm KMGTPEZY"
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr "/dev/null ist nicht verwendbar"
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "Fehler beim Schließen der Datei"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "die Eingabedatei ist auch die Ausgabedatei"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(keine)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr "Endzeit"
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "Rate min/mittel/max/abweichung"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "Übertragungsrate nicht gemessen"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "Nachricht nicht empfangen"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO wird auf diesem System nicht unterstützt"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "warnung: lesefehler erkannt"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "über den Lesefehler hinaus verschoben"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "Schreibfehler"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "ist weder eine normale Datei noch ein Blockgerät"
|
||||
|
||||
#~ msgid "state allocation failed"
|
||||
#~ msgstr "Speicherzuweisung für `state' fehlgeschlagen"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "konnte Dateiinformationen nicht lesen"
|
||||
|
||||
#~ msgid "is a directory"
|
||||
#~ msgstr "ist ein Verzeichnis"
|
||||
|
||||
#~ msgid "failed to generate sysfs filename"
|
||||
#~ msgstr "konnte Sysfs-Dateinamen nicht erzeugen"
|
||||
|
||||
#~ msgid "failed to read sysfs size file"
|
||||
#~ msgstr "konnte Größe der Sysfs-Datei nicht lesen"
|
||||
|
||||
#~ msgid "failed to open block device"
|
||||
#~ msgstr "konnte Blockgerät nicht öffnen"
|
||||
|
||||
#~ msgid "failed to determine size of block device"
|
||||
#~ msgstr "konnte Größe des Blockgeräts nicht ermitteln"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "Speicherzuweisung für `option' fehlgeschlagen"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "Speicherzuweisung für `argv' der Option fehlgeschlagen"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "konnte Terminalname nicht lesen"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "Sperrversuch fehlgeschlagen"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "konnte Terminal nicht öffnen"
|
||||
|
||||
#~ msgid "failed to seek to start of output"
|
||||
#~ msgstr "Konnte nicht zum Anfang der Ausgabe springen"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "konnte Datei nicht lesen"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "konnte Dateiinformationen für Ausgabe-Datei nicht lesen"
|
||||
|
||||
#~ msgid "history structure allocation failed"
|
||||
#~ msgstr "Speicherzuweisung für `history' fehlgeschlagen"
|
||||
|
||||
#~ msgid "file list allocation failed"
|
||||
#~ msgstr "Speicherzuweisung für die Dateiliste fehlgeschlagen"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "read-Aufruf fehlgeschlagen"
|
||||
|
||||
#~ msgid "file is not seekable"
|
||||
#~ msgstr "Datei ist nicht durchsuchbar"
|
||||
|
||||
#~ msgid "failed to seek past error"
|
||||
#~ msgstr "konnte den Fehler nicht überwinden"
|
||||
|
||||
#~ msgid "no transfer buffer allocated"
|
||||
#~ msgstr "Speicherzuweisung für den Transferpuffer fehlgeschlagen"
|
||||
|
||||
#~ msgid "failed to set interval timer"
|
||||
#~ msgstr "konnte Intervall-Timer nicht setzen"
|
||||
|
||||
#~ msgid "failed to clear interval timer"
|
||||
#~ msgstr "konnte Intervall-Timer nicht löschen"
|
||||
|
||||
#~ msgid "line position buffer allocation failed"
|
||||
#~ msgstr "Zuweisung des Zeilenpuffers fehlgeschlagen"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "select-Aufruf fehlgeschlagen"
|
||||
|
||||
#~ msgid "PID[:FD]"
|
||||
#~ msgstr "PID[:FD]"
|
||||
@@ -0,0 +1,615 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: pv 1.9.34\n"
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2026-03-24 23:25+0000\n"
|
||||
"Last-Translator: Ricky-Tigg <ricky-tigg@noreply.codeberg.org>\n"
|
||||
"Language-Team: Finnish <https://translate.codeberg.org/projects/pv/pv/fi/>\n"
|
||||
"Language: fi\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.16.2\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "näytä edistymispalkki"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "näytä kulunut aika"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "näytä arvioitu valmistumisaika"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "näytä absoluuttinen arvioitu valmistumisaika"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "näytä datan siirtonopeuden laskuri"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "näytä datan keskimääräisen siirtonopeuden laskuri"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "näytä siirrettyjen tavujen määrä"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "näytä käytössä olevan siirtopuskurin prosenttiosuus"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "näytä NUM viimeksi kirjoitettua tavua"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "MUOTO"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "aseta tulostemuodoksi MUOTO"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "tulosta prosentit, ei visuaalista tietoa"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "älä tulosta minkäänlaista siirtotietoa"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "näytä siirrettyjen bittien määrä"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "käsittele päätteitä 1000:n kertoimina 1024:n sijaan"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "älä näytä mitään, ennen kuin ensimmäinen tavu on siirretty"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "SEK"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "älä näytä mitään, ennen kuin SEC sekuntia on kulunut"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "KOKO"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "aseta arvioiduksi datan kooksi KOKO tavua"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "Jos kokoa ei tiedetä, näytä nopeus vs. maksiminopeus"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "laske rivit tavujen sijaan"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "rivit päättyvät nullilla"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "päivitä SEC sekunnin välein"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "laske keskimääräinen siirtonopeus SEC sekunnin ajalta (oletus 30 s)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "LEVEYS"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "oleta, että päätteen LEVEYS on merkkiä leveä"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "KORKEUS"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "oleta, että päätteen KORKEUS on merkkiä korkea"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "NIMI"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "lisää visuaalisiin tietoihin NIMI-etuliite"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "TYYLI"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "aseta oletuspalkkityyli TYYLI:lle"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "lähetä edistyminen myös SPECille"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "tulosta siirtotilastot lopussa"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "tuloste, vaikka vakiovirhe ei olisikaan päätelaite"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "käytä kohdistimen sijoittelun esc-sekvenssiä"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "TIEDOSTO"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "kirjoita tuloste tiedostoon TIEDOSTO oletustulosteen (stdout) sijaan"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "NOPEUS"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "rajoita siirron nopeudeksi NOPEUS tavua per sekunti"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "TAVUT"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "käytä puskuria, jonka koko on TAVUT"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "Älä koskaan käytä splice():tta, käytä aina luku-/kirjoitustoimintoa"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ohita lukuvirheet syötteessä"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "ohita virheet TAVUT:ssa lohkoissa kerrallaan"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "lopeta kun --size tavua on siirretty"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "tyhjennä välimuisti levylle jokaisen kirjoituksen jälkeen"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "käytä suoraa syötettä/lähtöä välimuistin ohittamiseen"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr "yritä etsiä tyhjätavujen kirjoittamisen sijaan"
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "hylkää syöte tulosteeseen kirjoittamisen sijaan"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
"kirjoita kaikki syöte tiedostoon TIEDOSTO ennen tulosteeseen kirjoittamista"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr "PID[:FD]|=NIMI|@LISTATIEDOSTO"
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "tarkkaile tiedostoa FD, jonka prosessi PID avasi"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "päivitä prosessin PID-asetukset"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr "näytä prosessin PID:n edistyminen"
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "tallenna prosessitunnus TIEDOSTO:on"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "näytä tämä ohje ja lopeta"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "näytä versiotiedot ja lopeta"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "kirjoita vianjäljityslokit tiedostoon TIEDOSTO"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Käyttö: %s [VALINTA] [TIEDOSTO]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Putkita TIEDOSTO(t), tai vakiosyöte, vakiotulosteeseen, monitoroinnin kanssa."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "Tuetut muotosekvenssit:"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Ilmoita ongelmista: %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(syöte)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "muistinvarausvirhe"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr "Listatiedostot eivät saa sisältää @-rivejä"
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "prosessitunnusta tai pid:fd-paria odotetaan"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "virheellinen prosessin ID"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr "numeerista arvoa ei ymmärretty"
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "kokonaislukuargumenttia odotetaan"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "numeerista argumenttia odotetaan"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr "puuttuva tiedostonimi"
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr "puuttuva prosessinimi"
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Suorita `%s --help' saadaksesi lisätietoja."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Suorita `%s -h' saadaksesi lisätietoja."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"rivitilaa tai siirtomuokkausvaihtoehtoja ei voi käyttää tiedostokuvauksia "
|
||||
"tarkasteltaessa"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"kohdistimen sijoittelua ei voi käyttää tiedostokuvauksia tarkasteltaessa"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "etäohjausta ei voi käyttää tiedostokuvauksia tarkasteltaessa"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr "etäkyselyä ei voi käyttää tiedostokuvauksia tarkasteltaessa"
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "tiedostoja ei voi siirtää tiedostokuvauksia tarkasteltaessa"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "ei saatavilla järjestelmissä, joissa ei ole /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr "etäohjausta ja etäkyselyä ei voi käyttää yhdessä"
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr "tiedostoja ei voi määrittää tämän vaihtoehdon kanssa"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Lisenssi: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
"Tämä on ilmaista ohjelmistoa: voit vapaasti muokata sitä ja levittää sitä "
|
||||
"uudelleen."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "TAKUUTA EI OLE, lain sallimissa rajoissa."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Projektin verkkosivu"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "lukitustiedoston avaaminen epäonnistui"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "signaalin keskeyttämä"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "virhe tiedoston sulkemisessa"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "syötetiedosto on myös tuotostiedosto"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(ei mitään)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "T/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "T"
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "nopeutta ei mitattu"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "viestiä ei vastaanotettu"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO ei ole tuettu tässä järjestelmässä"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "varoitus: lukuvirheitä havaittu"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "aiempi lukuvirhe ohitettu"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "kirjoitusvirhe"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "ei tavallinen tiedosto tai lohkolaite"
|
||||
|
||||
#~ msgid "state allocation failed"
|
||||
#~ msgstr "tilan allokointi epäonnistui"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "tiedoston tilastointi epäonnistui"
|
||||
|
||||
#~ msgid "is a directory"
|
||||
#~ msgstr "on hakemisto"
|
||||
|
||||
#~ msgid "failed to generate sysfs filename"
|
||||
#~ msgstr "sysfs-tiedostonimen luominen epäonnistui"
|
||||
|
||||
#~ msgid "failed to read sysfs size file"
|
||||
#~ msgstr "sysfs-kokotiedoston lukeminen epäonnistui"
|
||||
|
||||
#~ msgid "failed to open block device"
|
||||
#~ msgstr "lohkolaitteen avaaminen epäonnistui"
|
||||
|
||||
#~ msgid "failed to determine size of block device"
|
||||
#~ msgstr "lohkolaitteen koon päättely epäonnistui"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "vaihtoehtorakenteen allokointi epäonnistui"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "vaihtoehtorakenteen argv:n allokointi epäonnistui"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "päätelaitteen nimen hakeminen epäonnistui"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "lukitusyritys epäonnistui"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "päätelaitteen avaaminen epäonnistui"
|
||||
|
||||
#~ msgid "failed to seek to start of output"
|
||||
#~ msgstr "tulosteen käynnistyksen hakeminen epäonnistui"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "tiedoston lukeminen epäonnistui"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "tulostiedoston tilastointi epäonnistui"
|
||||
|
||||
#~ msgid "history structure allocation failed"
|
||||
#~ msgstr "historiarakenteen allokointi epäonnistui"
|
||||
|
||||
#~ msgid "file list allocation failed"
|
||||
#~ msgstr "tiedostolistan allokointi epäonnistui"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "luku epäonnistui"
|
||||
|
||||
#~ msgid "file is not seekable"
|
||||
#~ msgstr "tiedosto ei ole haettavissa"
|
||||
|
||||
#~ msgid "failed to seek past error"
|
||||
#~ msgstr "menneen virheen hakeminen epäonnistui"
|
||||
|
||||
#~ msgid "no transfer buffer allocated"
|
||||
#~ msgstr "siirtopuskuria ei ole allokoitu"
|
||||
|
||||
#~ msgid "failed to set interval timer"
|
||||
#~ msgstr "aikaväliajastimen asettaminen epäonnistui"
|
||||
|
||||
#~ msgid "failed to clear interval timer"
|
||||
#~ msgstr "aikaväliajastimen tyhjennys epäonnistui"
|
||||
|
||||
#~ msgid "line position buffer allocation failed"
|
||||
#~ msgstr "rivin sijaintipuskurin allokointi epäonnistui"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "valintakutsu epäonnistui"
|
||||
@@ -0,0 +1,651 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2026-08-01 18:32+0000\n"
|
||||
"Last-Translator: a-j-wood <a-j-wood@noreply.codeberg.org>\n"
|
||||
"Language-Team: French <https://translate.codeberg.org/projects/pv/pv/fr/>\n"
|
||||
"Language: fr\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 2026.7.1\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
"From: Andrew Wood <ivarch@ubik>\n"
|
||||
"Xgettext-Options: --default-domain=pkgbuild --directory=./.pkgdir --add-"
|
||||
"comments --keyword=_ --keyword=N_\n"
|
||||
"Files: src/getopt/getopt.c src/getopt/getopt1.c src/version.c src/main/"
|
||||
"init.c src/main/help.c src/main/xpmptr.c src/guts/load.c src/guts/stop.c src/"
|
||||
"guts/configure.c src/guts/make.c src/guts/install.c src/guts/prefs.c src/ui/"
|
||||
"generate.c src/ui/main.c src/ui/xpm.c src/ui/status.c src/ui/activate.c src/"
|
||||
"ui/handlers/main.c src/ui/handlers/package.c src/ui/handlers/prefs.c src/ui/"
|
||||
"handlers/dirsel.c src/ui/handlers/popup.c src/ui/handlers/help.c src/ui/"
|
||||
"textout.c src/ui/report.c src/ui/callback.c src/nls/intl/bindtextdom.c src/"
|
||||
"nls/intl/dcgettext.c src/nls/intl/dgettext.c src/nls/intl/finddomain.c src/"
|
||||
"nls/intl/gettext.c src/nls/intl/loadmsgcat.c src/nls/intl/localealias.c src/"
|
||||
"nls/intl/textdomain.c src/nls/intl-cat/cat-compat.c src/nls/intl-gett/intl-"
|
||||
"compat.c\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "afficher la barre de progression"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "afficher le temps écoulé"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "afficher l'heure approximative de l'achèvement de la tâche"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "afficher l'heure absolute de l'achèvement de la tâche"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "afficher le taux de tranfert des données"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "afficher le compteur de taux moyen de transfert de données"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "afficher le nombre d'octets transférés"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "afficher le pourcentage de tampon de transfert utilisé"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "afficher les derniers NUM octets écrits"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "définir le format de sortie sur FORMAT"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "imprimer en pourcentage plutôt que des informations visuelles"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "n'afficher aucune information de transfert"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "afficher le nombre de bits transférés"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "traiter les suffixes comme des multiples de 1000 au lieu de 1024"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "ne rien afficher avant qu'au moins un octet soit tranféré"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "SEC"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "ne rien afficher jusqu'à ce que SEC secondes se soient écoulées"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "TAILLE"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "ajuster la taille estimée des données à TAILLE octets"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
"si la taille est inconnue, afficher le taux de transfert par rapport au taux "
|
||||
"de transfert max"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "compter les lignes au lieu des octets"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "les lignes sont terminées par un caractère nul"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "mettre à jour toutes les SEC secondes"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
"calculer le taux moyen d'après les SEC dernières secondes (30s par défaut)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "LARGEUR"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "présumer la largeur du terminal à LARGEUR caractères"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "HAUTEUR"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "présumer la hauteur du terminal à HAUTEUR lignes"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "NOM"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "préfixer les informations visuelles avec NOM"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "STYLE"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "définir le style de barre par défaut à STYLE"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr "SPÉCIFICATION"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "aussi envoyer la progression à SPÉCIFICATION"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr "mettre à jour l'état de progression du terminal avec OSC 9;4 (ConEmu)"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "afficher les statistiques de transfert à la fin"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
"imprimer vers la sortie d'erreur standard même si ce n'est pas un terminal"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utiliser les séquences d'échappements de positionnement de curseur"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "FICHIER"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "écrire la sortie dans FICHIER au lieu de la sortie standard"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "TAUX"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limite le taux de transfert à TAUX octets par seconde"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "OCTETS"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "utiliser une mémoire tampon de OCTETS octets"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "ne jamais utiliser splice(), toujours utiliser read/write"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr "définir la taille du tampon de mémoire du tube à OCTETS octets"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignorer les erreurs de lecture dans l'entrée"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "ignorer les erreurs dans OCTETS blocs à la fois"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "arrêter après le transfert de --size octets"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "vider le cache sur le disque après chaque écriture"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "utiliser les E/S directes pour contourner le cache"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr "écrire des trous dans le fichier au lieu d'octets nuls"
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "rejeter l'entrée au lieu de l'écrire vers la sortie"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "écrire toute l'entrée vers FICHIER avant de l'écrire vers la sortie"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr "PID[:FD]|=NOM|@FICHIER"
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "surveiller le fichier FD ouvert par le processus PID"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "mettre à jour la configuration du processus PID"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr "afficher la progression du processus PID"
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
"exécuter une commande et surveiller son entrée standard, sa sortie ou les "
|
||||
"deux"
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "enregistrer l'ID de processus dans FICHIER"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "afficher cette aide puis quitter"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "afficher la version puis quitter"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "écrire les journaux de déboggage vers FICHIER"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Utilisation : %s [OPTIONS] [FICHIER]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Concaténer FICHIER(s), ou l'entrée standard, sur la sortie standard avec "
|
||||
"monitorage."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "Séquences de formatage supportées :"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "SVP rapporter tous bogues à %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(entrée)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr "une commande à exécuter doit être spécifiée"
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "échec d'allocation mémoire"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr "les fichiers de liste ne peuvent pas contenir de lignes « @ »"
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID de processus ou paire pid:fd attendue"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processus non valide"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr "valeur numérique non comprise"
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "valeur entière attendue"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "valeur numérique attendue"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr "nom de fichier manquant"
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr "nom de processus manquant"
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr "côté inacceptable"
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Essayez `%s --help' pour plus d'informations."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Essayez `%s -h' pour plus d'informations."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser le mode ligne ou les options de modificateur de "
|
||||
"transfert lors de la visualisation des descripteurs de fichiers"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser le positionnement du curseur lors de la visualisation "
|
||||
"des descripteurs de fichier"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser la télécommande lors de la visualisation des "
|
||||
"descripteurs de fichiers"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser une requête distante lorsque vous regardez des "
|
||||
"descripteurs de fichiers"
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible de transférer des fichiers lorsque vous regardez des descripteurs "
|
||||
"de fichiers"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "non disponible sur les systèmes sans /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
"impossible d'utiliser simultanément le contrôle à distance et "
|
||||
"l'interrogation à distance"
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr "impossible d'utiliser mode moniteur avec cette option"
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
"impossible d'utiliser mode moniteur avec le stockage et la retransmission"
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr "les fichiers ne peuvent pas être spécifiés avec cette option"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "License : GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
"Ceci est un logiciel libre : vous êtes libre de le modifier et de le "
|
||||
"redistribuer."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Il n'y a AUCUNE GARANTIE, dans la mesure permise par la loi."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Site web du projet"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "échec de l'ouverture du fichier de verrouillage"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "interrompu par un signal"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr "/dev/null n'est pas utilisable"
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "erreur à la fermeture du fichier"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "le fichier d'entrée est aussi le fichier de sortie"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(aucun)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "O/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "O"
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "taux min/moy/max/écart-type"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "taux non mesuré"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "message non reçu"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO non pris en charge sur ce système"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "avertissement : erreurs de lecture détectées"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "erreur de lecture dépassée"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "erreur d'écriture"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "pas un fichier ordinaire ou un périphérique de bloc"
|
||||
|
||||
#~ msgid "state allocation failed"
|
||||
#~ msgstr "échec de l'allocation de mémoire de condition"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "échec à statuer sur le fichier"
|
||||
|
||||
#~ msgid "is a directory"
|
||||
#~ msgstr "est un répertoire"
|
||||
|
||||
#~ msgid "failed to generate sysfs filename"
|
||||
#~ msgstr "échec de génération du nom de fichier sysfs"
|
||||
|
||||
#~ msgid "failed to read sysfs size file"
|
||||
#~ msgstr "échec de la lecture de la taille du fichier sysfs"
|
||||
|
||||
#~ msgid "failed to open block device"
|
||||
#~ msgstr "échec de l'ouverture du périphérique de bloc"
|
||||
|
||||
#~ msgid "failed to determine size of block device"
|
||||
#~ msgstr "échec de l'évaluation de la taille du périphérique de bloc"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "l'allocation pour la structure d'une option a échoué"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "l'allocation pour la structure de l'option argv a échoué"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "échec de lecture du nom du terminal"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "échec de la tentative de verrouillage"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "échec de l'ouverture du terminal"
|
||||
|
||||
#~ msgid "failed to seek to start of output"
|
||||
#~ msgstr "ne peut pas passer au début de la sortie"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "la lecture du fichier a échoué"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "échec à statuer sur le fichier de sortie"
|
||||
|
||||
#~ msgid "history structure allocation failed"
|
||||
#~ msgstr "l'allocation de la structure de l'historique a échoué"
|
||||
|
||||
#~ msgid "file list allocation failed"
|
||||
#~ msgstr "échec de l'allocation de la liste de fichiers"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "la lecture a échoué"
|
||||
|
||||
#~ msgid "file is not seekable"
|
||||
#~ msgstr "ne peut pas se déplacer dans le fichier"
|
||||
|
||||
#~ msgid "failed to seek past error"
|
||||
#~ msgstr "n'a pas réussi à dépasser l'erreur"
|
||||
|
||||
#~ msgid "no transfer buffer allocated"
|
||||
#~ msgstr "aucun tampon de transfert alloué"
|
||||
|
||||
#~ msgid "failed to set interval timer"
|
||||
#~ msgstr "La définition de l'intervalle du minuteur a échoué"
|
||||
|
||||
#~ msgid "failed to clear interval timer"
|
||||
#~ msgstr "La réinitialisation des intervalles du minuteur a échoué"
|
||||
|
||||
#~ msgid "line position buffer allocation failed"
|
||||
#~ msgstr ""
|
||||
#~ "L'allocation de la position de la ligne de la mémoire tampon a échoué"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "l'appel de sélection a échoué"
|
||||
|
||||
#~ msgid "PID[:FD]"
|
||||
#~ msgstr "PID[:FD]"
|
||||
|
||||
#~ msgid "failed to set alarm signal handler"
|
||||
#~ msgstr "échec de la définition du gestionnaire de signal d'alarme"
|
||||
@@ -0,0 +1,541 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: pv 1.11.0\n"
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2026-08-07 19:25+0000\n"
|
||||
"Last-Translator: ldm <ldm@noreply.codeberg.org>\n"
|
||||
"Language-Team: Italian <https://translate.codeberg.org/projects/pv/pv/it/>\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2026.7.1\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "mostra la barra dei progressi"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "mostra tempo trascorso"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "mostra tempo stimato di completamento"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "mostra l'orario di tempo stimato di completamento"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "mostrare il contatore della velocità di trasferimento dati"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "mostrare la velocità media di trasferimento dati"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "mostra numero di byte trasferiti"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "mostra la percentuale del buffer di trasferimento in uso"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "mostra NUM bytes ultimo scritto"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "impostare il formato output in FORMAT"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "percentuali di output, non informazioni visive"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "non mostrare alcuna informazione di trasferimento"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "mostra numero di bit trasferiti"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "trattare i suffissi come multipli di 1000 piuttosto che 1024"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "non mostrare nulla fino al primo byte trasferito"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "SEC"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "non mostrare nulla fino a quando non sono passati SEC secondi"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "DIM"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "imposta la dimensione stimata dei dati per DIM bytes"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "se dimensioni sconosciute, mostrare tasso di trasferimento vs tasso massimo"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "contare le linee invece dei bytes"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "le righe terminano con un carattere nullo"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aggiornamento ogni SEC secondi"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "calcolare il tasso medio negli ultimi SEC secondi (predefinito 30s)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "LARGHEZZA"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "assumere il terminale largo LARGHEZZA caratteri"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "ALTEZZA"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "assumere terminale alto ALTEZZA righe"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "NOME"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "anteponi NOME alle informazioni visive"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "STILE"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "impostare lo stile predefinito della barra a STILE"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr "SPEC"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "inviare i progressi anche a SPEC"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr "impostare lo stato di avanzamento del terminale con OSC 9;4 (ConEmu)"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "mostra statistiche di trasferimento alla fine"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "output anche se standard error non è un terminale"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utilizzare le sequenze escape di posizionamento del cursore"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "FILE"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "scrivere output su FILE invece che stdout"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "TASSO"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limite di trasferimento a TASSO byte al secondo"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "BYTE"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "utilizzare un buffer di dimensione BYTE"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "mai usare splice(), usare sempre lettura/scrittura"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr "impostare la dimensione del pipe buffer a BYTE"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "saltare gli errori di lettura in input"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "passare errori passati in blocchi BYTE"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "stop dopo aver trasferito --size byte"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "svuotare la cache sul disco dopo ogni scrittura"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "utilizzare direct I/O per bypassare la cache"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr "prova a cercare invece di scrivere byte nulli"
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "scartare l'input invece di scrivere sull'output"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "scrivere tutti gli input su FILE prima di scrivere su output"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr "PID[:FD]|=NOME|@FILE"
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "visualizza il file FD aperto dal processo PID"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "impostazioni di aggiornamento del processo PID"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr "mostrare il progresso del processo PID"
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
"eseguire un comando e monitorare il suo standard input, output, o entrambi"
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "salvare ID processo in FILE"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "mostra questo help ed esce"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "stampa le informazioni sulla versione ed esce"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "scrivi i log di debug su FILE"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Uso: %s [OPZIONE] [FILE]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Concatena i FILE, o lo standard input, allo standard output, con "
|
||||
"monitoraggio."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "Sequenze di formato supportate:"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Per favore segnalare i bug a: %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(input)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr "un comando da eseguire deve essere specificato"
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "fallimento nell'allocazione della memoria"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr "file di elenco non possono contenere linee @"
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "è previsto un ID di processo o una coppia pid:fd"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID processo non valido"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr "valore numerico non compreso"
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "argomento integer previsto"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "argomento numerico previsto"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr "nome del file mancante"
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr "nome del processo mancante"
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr "specifica del lato non valida"
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Usare «%s --help» per ulteriori informazioni."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Usare «%s -h» per ulteriori informazioni."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"non è possibile utilizzare la modalità riga o il modificatore di "
|
||||
"trasferimento durante la visualizzazione dei descrittori di file"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"non può utilizzare il posizionamento del cursore durante la visualizzazione "
|
||||
"dei descrittori di file"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "non può usare il telecomando quando si guarda i descrittori di file"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr "non può utilizzare query remoto quando si guarda i descrittori di file"
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"non può trasferire i file durante la visualizzazione dei descrittori di file"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "non disponibile su sistemi senza /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr "non può utilizzare il telecomando e la query remota insieme"
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr "la modalità monitor non può essere specificata con questa opzione"
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr "modalità monitor non può essere utilizzato con negozio e in avanti"
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr "i file non possono essere specificati con questa opzione"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Licenza: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr "Questo è software libero: è possibile modificarlo e ridistribuirlo."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Non c'è ALCUNA GARANZIA, nei limiti permessi dalla legge."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Sito web del progetto"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "non è riuscito ad aprire il file di blocco"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "interrotta da un segnale"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr "/dev/null non è utilizzabile"
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "errore nel chiudere il file"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "il file di input coincide con quello di output"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(nessuno)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "tasso min/med/mas/mdev"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "tasso non misurato"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "messaggio non ricevuto"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO non supportato su questo sistema"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "avvertimento: errori di lettura rilevati"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "saltato l'errore di lettura"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "errore di scrittura"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "non è un file regolare o un dispositivo a blocchi"
|
||||
@@ -0,0 +1,539 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: pv 1.9.34\n"
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2026-05-16 19:25+0000\n"
|
||||
"Last-Translator: a-j-wood <a-j-wood@noreply.codeberg.org>\n"
|
||||
"Language-Team: Georgian <https://translate.codeberg.org/projects/pv/pv/ka/>\n"
|
||||
"Language: ka\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.17.1\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "პროგრესის ზოლის ჩვენება"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "გასული დროის ჩვენება"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "სავარაუდო დასრულების დროის ჩვენება"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "დასრულების აბსოლუტური სავარაუდო დროის ჩვენება"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "მონაცემთა გადაცემის სიჩქარის ჩვენება"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "საშუალო მონაცემთა გადაცემის სიჩქარის ჩვენება"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "გადატანილი ბაიტების რაოდენობის ჩვენება"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "გამოყენებული გადაცემის ბუფერის პროცენტული მაჩვენებლის ჩვენება"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "ႬႭႫ"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "ბოლოს დაწერილი ႬႭႫ ბაიტის ჩვენება"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "ႴႭႰႫႠႲႨ"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "გამომავალი ფორმატის დაყენება ႴႭႰႫႠႲႨ"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "გამომავალი პროცენტები, არა ვიზუალური ინფორმაცია"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "პროგრესის ინფორმაცია არ აჩვენოთ"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "გადაცემული ბიტების რაოდენობის ჩვენება"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "სუფიქსების 1000-ის ჯერადად განხილვა 1024-ის ნაცვლად"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "არაფერი აჩვენოს პირველი ბაიტის გადატანამდე"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "ႼႠႫ"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "არაფერი აჩვენოს ႼႠႫ წამების გასვლამდე"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "ႦႭႫႠ"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "მონაცემთა სავარაუდო ზომის ႦႭႫႠ ბაიტებზე დაყენება"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "თუ ზომა უცნობია, აჩვენეთ სიჩქარე მაქსიმალურ სიჩქარესთან შედარებით"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "ბაიტების ნაცვლად ხაზების დათვლა"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "ხაზები ნულით დასრულებულია"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "განახლება ყოველ ႼႠႫ წამში"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
"გამოთვალეთ საშუალო მაჩვენებელი ბოლო ႼႠႫ წამების განმავლობაში (ნაგულისხმევი "
|
||||
"30 წმ)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "ႱႨႢႠႬႤ"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "ვივარაუდოთ, რომ ტერმინალი ႱႨႢႠႬႤ სიმბოლოს სიგანისაა"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "ႱႨႫႠႶႪႤ"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "ვივარაუდოთ, რომ ტერმინალი ႱႨႫႠႶႪႤ რიგის სიმაღლისაა"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "ႱႠႾႤႪႨ"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "გამომავალი ხაზის დასაწყისში ႱႠႾႤႪႨ-ის ჩვენება"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "ႱႲႨႪႨ"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "ნაგულისხმევი ზოლის სტილი ႱႲႨႪႨ-ზე დააყენეთ"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr "ႱႮႤႺႨႴႨႩႠ"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "ასევე გაუგზავნეთ პროგრესი ႱႮႤႺႨႴႨႩႠ-ს"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "სტატისტიკის ჩვენება ბოლოს"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "გამომავალი მაშინაც კი, თუ სტანდარტული შეცდომა ტერმინალი არ არის"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "კურსორის პოზიციონირება ტერმინალის კოდებით"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "ႴႠႨႪႨ"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "ჩაწერეთ გამომავალი ႴႠႨႪႨ-ში სტანდარტული გამომავალის ნაცვლად"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "ႱႨႹႵႠႰႤ"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "სიჩქარის შეზღუდვა წამში ႱႨႹႵႠႰႤ ბაიტამდე"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "ႡႠႨႲႤႡႨ"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "გამოიყენეთ ႡႠႨႲႤႡႨ ბუფერის ზომა"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "არასდროს გამოიყენოთ splice(), ყოველთვის გამოიყენეთ წაკითხვა/ჩაწერა"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr "მილის ბუფერის ზომა დააყენეთ ႡႠႨႲႤႡႨ ბაიტზე"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "შეყვანის შეცდომების გამოტოვება"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "შეცდომების გამოტოვება ႡႠႨႲႤႡႨ ბაიტის ბლოკებში"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "შეჩერება --size ბაიტების გადატანის შემდეგ"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "დისკის ჩაწერის ქეშის გასუფთავება ყოველი ჩაწერის შემდეგ"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "ქეშის გვერდის ავლით პირდაპირი შეყვანის/გამოყვანის გამოყენებით"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr "დატოვეთ ხვრელები გამომავალში ნულოვანი ბაიტების ჩაწერის ნაცვლად"
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "შეყვანის გაუქმება გამოსავალში ჩაწერის ნაცვლად"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "ყველა შემავალი მონაცემი ႴႠႨႪႨ-ში ჩაწერეთ გამოსავალში ჩაწერამდე"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr "ႮႨႣ[:ႴႠ]|=ႱႠႾႤႪႨ|@ႴႠႨႪႨ"
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "ფაილის აღწერის ყურება ႴႠ გახსნილია ႮႨႣ პროცესის მიერ"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "ႮႨႣ"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "პროცესის ႮႨႣ-ის პარამეტრების განახლება"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr "პროცესის ႮႨႣ პროგრესის ჩვენება"
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
"ბრძანების გაშვება და მისი სტანდარტული შეყვანის, გამომავალი ან ორივეს "
|
||||
"მონიტორინგი"
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "პროცესის იდენტიფიკატორის შენახვა ႴႠႨႪႨ-ში"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "აჩვენეთ ეს დახმარება და გადით"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "ვერსიის ინფორმაციის ჩვენება და გასვლა"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "გამართვის ჟურნალების ႴႠႨႪႨ-ში ჩაწერა"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "გამოყენება: %s [ႠႰႹႤႥႠ] [ႴႠႨႪႨ]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr "შეყვანის ფაილების გადატანა გამოსავალზე მონიტორინგით."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "მხარდაჭერილი ფორმატის თანმიმდევრობები:"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "ნებისმიერი შეცდომის შესახებ, გთხოვთ, შეატყობინოთ შემდეგ მისამართზე: %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(შეყვანა)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr "შესასრულებელი ბრძანება უნდა იყოს მითითებული"
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "მეხსიერების გამოყოფის შეცდომა"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr "სიის ფაილები არ შეიძლება შეიცავდეს \"@\" ხაზებს"
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr "ფაილის სახელი აკლია"
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "დამატებითი ინფორმაციისთვის სცადეთ `%s --help'."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "დამატებითი ინფორმაციისთვის სცადეთ `%s -h'."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "ლიცენზია: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
"ეს არის უფასო პროგრამული უზრუნველყოფა: თქვენ შეგიძლიათ შეცვალოთ და ხელახლა "
|
||||
"გაავრცელოთ იგი."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "კანონით დაშვებული ფარგლებში, გარანტია არ არსებობს."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "პროექტის ვებსაიტი"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "დაბლოკვის ფაილის გახსნა ვერ მოხერხდა"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "შეწყვეტილია სიგნალის მიერ"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr "/dev/null არ არის გამოსაყენებელი"
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "ფაილის დახურვის შეცდომა"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "შეტანის ფაილი ასევე გამოსატანიცაა"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(არცერთი)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "სიჩქარე მინიმალური/საშუალო/მაქსიმალური/სტანდარტული გადახრა"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "სიჩქარე არ იზომებოდა"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "შეტყობინება არ არის მიღებული"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "გაფრთხილება: წაკითხვის შეცდომები აღმოჩენილია"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "ჩაწერის შეცდომა"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,639 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2026-08-01 18:32+0000\n"
|
||||
"Last-Translator: a-j-wood <a-j-wood@noreply.codeberg.org>\n"
|
||||
"Language-Team: Polish <https://translate.codeberg.org/projects/pv/pv/pl/>\n"
|
||||
"Language: pl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 2026.7.1\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "pokaż pasek postępu"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "pokaż upływający czas"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "pokaż szacowany czas ukończenia"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "pokaż bezwzględny szacowany czas ukończenia"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "pokaż licznik prędkości przesyłania"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "pokaż licznik uśrednionej prędkości przesyłania"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "pokaż ilość przesłanych bajtów"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "pokaż procentowe użycie bufora transferu"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "LICZBA"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "pokaż ostatnie LICZBA przesłanych bajtów"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "ustaw FORMAT jako format wyjściowy"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "wyświetl wyjście procentowo, bez graficznej prezentacji"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "nie wyświetlaj żadnych informacji o przesyłaniu"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "pokaż ilość przesłanych bitów"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "traktuj przyrostki jako wielokrotności 1000 zamiast 1024"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "nie wyświetlaj nic aż do pierwszego przesłanego bajtu"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "SEKUNDY"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "nie wyświetlaj nic do momentu upłynięcia SEKUNDY sekund"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "ROZMIAR"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "ustaw oczekiwany rozmiar danych na ROZMIAR bajtów"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
"jeśli rozmiar nie jest znany, wyświetl zestawienie prędkości do maksymalnej "
|
||||
"prędkości"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "zliczaj linie zamiast bajty"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "linie są zakończone znakiem NUL"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualizuj co każde SEKUNDY sekund"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
"oblicz średnią prędkość transferu na podstawie poprzednich SEKUNDY sekund "
|
||||
"(domyślnie 30 s)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "SZEROKOŚĆ"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "przyjmij, że terminal ma szerokość SZEROKOŚĆ znaków"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "WYSOKOŚĆ"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "przyjmij, że terminal ma wysokość WYSOKOŚĆ linii"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "NAZWA"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "poprzedź informacje prefiksem NAZWA"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "STYL"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "ustaw domyślny styl paska postępu na STYL"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr "SPEC"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "wysyłaj postęp również do SPEC"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr "aktualizacja stanu zaawansowania terminala za pomocą OSC 9;4 (ConEmu)"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "wyświetl na końcu statystyki transferu"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "pokaż wyjście nawet standardowe wyjście błędu nie jest terminalem"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "używaj znaków ucieczki do pozycjonowania kursora"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "PLIK"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "zapisz wyjście do PLIK zamiast do wyjścia standardowego"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "PRĘDKOŚĆ"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "ogranicz przesyłane dane do PRĘDKOŚĆ bajtów na sekundę"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "BAJTY"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "użyj bufora o rozmiarze BAJTY"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nigdy nie używaj splice(), zawsze używaj read/write"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr "użyj bufora potokowego o rozmiarze BAJTY"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "pomijaj błędy odczytu wejścia"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "pomijaj błędy w blokach po BAJTY bajtów na raz"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "zakończ po przesłaniu --size bajtów"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "wymuś zapis pamięci podręcznej na dysk po każdym zapisie"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
"użyj bezpośredniego wejścia/wyjścia celem pominięcia pamięci podręcznej"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr "próbuj przewinąć zamiast wypisywać zerowe bajty"
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "zignoruj dane wejściowe zamiast wyświetlić je na wyjściu standardowym"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
"zapisz wszystkie dane wejściowe do PLIK przed wyświetleniem ich na wyjściu"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr "PID[:FD]|=NAZWA|@PLIKLISTY"
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "obserwuj plik FD otworzony przez proces PID"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "zaktualizuj ustawienia procesu PID"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr "pokaż postęp procesu PID"
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr "uruchom polecenie i monitoruj jego wejście i/lub wyjście standardowe"
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "zapisz ID procesu do PLIK"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "wyświetl te informacje z pomocą i wyjdź"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "wyświetl informacje o wersji i wyjdź"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "zapisz logi debugujące do PLIK"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Sposób użycia: %s [OPCJA] [PLIK]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Łączenie PLIK(ów) lub wejścia standardowego, do wyjścia standardowego z "
|
||||
"monitorowaniem."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "Wspierane sekwencje formatowania:"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Proszę przesyłać zgłoszenia błędów do %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(wejście)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr "polecenie do uruchomienia musi zostać określone"
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "błąd przydziału pamięci"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr "pliki list nie mogą zawierać linii wykorzystujących @"
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "oczekiwany proces ID lub para PID:FD"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "niepoprawne ID procesu"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr "wartość liczbowa niezrozumiana"
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "oczekiwany argument typu liczby całkowitej"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "oczekiwany argument liczbowy"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr "brakująca nazwa pliku"
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr "brakująca nazwa procesu"
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr "niepoprawne określenie monitorowanych stron"
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Spróbuj `%s --help' by uzyskać więcej informacji."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Spróbuj `%s -h' by uzyskać więcej informacji."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"nie można użyć trybu zliczania linii lub opcji modyfikujących przesył "
|
||||
"łącznie z opcją obserwowania deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"nie można użyć pozycjonowania kursora łącznie z opcją obserwowania "
|
||||
"deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"nie można korzystać ze zdalnego sterowania łącznie z obserwowaniem "
|
||||
"deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
"nie można korzystać ze zdalnego odczytu łącznie z obserwowaniem deskryptorów "
|
||||
"plików"
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "nie można przesyłać plików z opcją obserwowania deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "niedostępne na systemach bez /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr "nie można użyć zdalnego sterowania i zdalnego odczytu jednocześnie"
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr "tryb monitorowania nie może być określony z tą opcją"
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr "tryb monitorowania nie może być użyty z store-and-forward"
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr "pliki nie mogą być określone przy użyciu tej opcji"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Licencja: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr "To jest wolne oprogramowanie: masz prawo do zmian i redystrybucji."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Nie udziela się GWARANCJI w zakresie dozwolonym przez prawo."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Strona projektu"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "nie udało się otworzyć pliku blokowania zasobów"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "przerwany przez sygnał"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr "/dev/null nie nadaje się do użytku"
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "błąd zamknięcia pliku"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "plik wejściowy jest również plikiem wyjściowym"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(brak)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
# "Przewidywany czas ukończenia" for ETA is too long
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "prędkość min/śr/max/odch"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "prędkość niezmierzona"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "wiadomość nieodebrana"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO nie jest wspierane na tym systemie"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "ostrzeżenie: błędy odczytu wykryte"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "pominięto błąd odczytu"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "błąd zapisu"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "plik nie jest plikiem regularnym lub urządzeniem blokowym"
|
||||
|
||||
#~ msgid "state allocation failed"
|
||||
#~ msgstr "alokacja stanu programu nie powiodła się"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "nie udało się wykonać operacji stat na pliku"
|
||||
|
||||
#~ msgid "is a directory"
|
||||
#~ msgstr "jest katalogiem"
|
||||
|
||||
#~ msgid "failed to generate sysfs filename"
|
||||
#~ msgstr "nie udało się wygenerować nazwy pliku dla sysfs"
|
||||
|
||||
#~ msgid "failed to read sysfs size file"
|
||||
#~ msgstr "nie udało się odczytać rozmiaru pliku sysfs"
|
||||
|
||||
#~ msgid "failed to open block device"
|
||||
#~ msgstr "nie udało się otworzyć urządzenia blokowego"
|
||||
|
||||
#~ msgid "failed to determine size of block device"
|
||||
#~ msgstr "nie udało się ustalić rozmiaru urządzenia blokowego"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "nie udało się zaalokować struktur opcji"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "nie udało się zaalokować struktur opcji argv"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "nie udało się uzyskać nazwy terminala"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "blokada zasobów nie powiodła się"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "nie udało się otworzyć terminala"
|
||||
|
||||
#~ msgid "failed to seek to start of output"
|
||||
#~ msgstr "nie udało się przewinąć wyjścia do początku"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "nie udało się odczytać pliku"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "nie udało się wykonać operacji stat na pliku wyjściowym"
|
||||
|
||||
#~ msgid "history structure allocation failed"
|
||||
#~ msgstr "nie udało się zaalokować struktury historii"
|
||||
|
||||
#~ msgid "file list allocation failed"
|
||||
#~ msgstr "nie udało się zaalokować listy plików"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "błąd odczytu"
|
||||
|
||||
#~ msgid "file is not seekable"
|
||||
#~ msgstr "pliku nie da się przewijać"
|
||||
|
||||
#~ msgid "failed to seek past error"
|
||||
#~ msgstr "nie udało się przewinąć za błąd"
|
||||
|
||||
#~ msgid "no transfer buffer allocated"
|
||||
#~ msgstr "brak zaalokowanego bufora transferu"
|
||||
|
||||
#~ msgid "failed to set interval timer"
|
||||
#~ msgstr "nie udało się ustawić interwału czasowego"
|
||||
|
||||
#~ msgid "failed to clear interval timer"
|
||||
#~ msgstr "nie udało się wyczyścić interwału czasowego"
|
||||
|
||||
#~ msgid "line position buffer allocation failed"
|
||||
#~ msgstr "alokacja buforu pozycji linii nie powiodła się"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "nie udało się wywołać funkcji select"
|
||||
|
||||
#~ msgid "process list allocation failed"
|
||||
#~ msgstr "nie udało się zaalokować listy procesów"
|
||||
|
||||
#~ msgid "file descriptor list allocation failed"
|
||||
#~ msgstr "nie udało się zaalokować listy deskryptorów plików"
|
||||
|
||||
#~ msgid "PID[:FD]"
|
||||
#~ msgstr "PID[:FD]"
|
||||
@@ -0,0 +1,583 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: pt\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "exibe barra de progressão"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "exibe tempo passado"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "exibe o tempo estimado de término"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "exibe o tempo absoluto estimado de término"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "exibe a taxa de transferência"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "exibe o contador da taxa média de transferência de dados"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "exibe a quantidade de bytes transferidos"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "exibe a porcentagem de buffer de transferência em uso"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "exibe NUM bytes gravados pela última vez"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "definir o formato de saída para FORMAT"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "exibe apenas as porcentagens, sem informações visuais"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "executa programa sem exibir quaisquer informações"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "não exibe nada até iniciar o processamento"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "não exibir nada até que os segundos SEC tenham passado"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "seta a quantidade estimada de dados em SIZE bytes"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "contar linhas em vez de bytes"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "linhas são terminadas em nulo"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "atualiza informações a cada SEC segundos"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "presuma que o terminal tem WIDTH caracteres de largura"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "presuma que o terminal tem HEIGHT caracteres de altura"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "exibe NAME antes das demais informações"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "gera dados mesmo que a saída de erro seja redirecionada"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utiliza caracteres de escape para posicionar o cursor"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limita a transferência a RATE bytes por segundo"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "use um tamanho de buffer de BYTES"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nunca use splice(), sempre use read/write"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignorar erros de leitura em entrada"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "parar após --size bytes terem sido transferidos"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "assistir arquivo FD aberto pelo processo PID"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "atualizar as configurações do processo PID"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "salvar ID do processo em FILE"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "exibe esta tela de ajuda e termina"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "exibe a versão e termina"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Uso: %s [OPÇÕES] [ARQUIVOS]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Concatena ARQUIVO(s) ou a entrada padrão e grava na saída padrão, com "
|
||||
"monitoramento."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Por favor, reporte quaisquer defeitos para %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "falha de alocação de memória"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID do processo ou par pid:fd esperado"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processo inválido"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "argumento inteiro esperado"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "argumento numérico esperado"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Tente `%s --help' para maiores informações."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Tente `%s -h' para maiores informações."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"não pode usar o modo de linha ou opções de modificador de transferência ao "
|
||||
"assistir os descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"não pode usar o posicionamento do cursor ao observar os descritores de "
|
||||
"arquivo"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "não pode usar o controle remoto ao assistir os descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "não pode transferir arquivos ao assistir descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "não disponível em sistemas sem /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "erro ao abrir arquivo de bloqueio"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "interrompido por um sinal"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "erro ao fechar o ficheiro"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "ficheiro de entrada também é a saída"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "mensagem não recebida"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO não suportado neste sistema"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "aviso: erros de leitura detectados"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "ignorado erro de leitura"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "erro de escrita"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "não é um arquivo regular ou dispositivo de bloqueio"
|
||||
|
||||
#~ msgid "state allocation failed"
|
||||
#~ msgstr "alocação de memória de status falhou"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "erro obtendo informações do arquivo"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "erro na alocação da estrutura de opções"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "erro na alocação da estrutura de opções argv"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "erro ao ler o nome do terminal"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "tentativa de bloqueio falhou"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "erro abrindo o terminal"
|
||||
|
||||
#~ msgid "failed to seek to start of output"
|
||||
#~ msgstr "não pode mover para o início da produção"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "erro lendo o arquivo"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "erro obtendo informações do arquivo de saída"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "erro de leitura"
|
||||
|
||||
#~ msgid "file is not seekable"
|
||||
#~ msgstr "não pode mover dentro do arquivo"
|
||||
|
||||
#~ msgid "failed to seek past error"
|
||||
#~ msgstr "não pode ir além do erro"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "erro na chamada da função select"
|
||||
@@ -0,0 +1,530 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: pv 1.11.0\n"
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Language-Team: Romanian <https://translate.codeberg.org/projects/pv/pv/ro/>\n"
|
||||
"Language: ro\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,600 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2026-08-17 12:27+0000\n"
|
||||
"Last-Translator: some_user <some_user@noreply.codeberg.org>\n"
|
||||
"Language-Team: Russian <https://translate.codeberg.org/projects/pv/pv/ru/>\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 2026.8.1\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "показать полосу прогресса"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "показать прошедшее время"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "показать примерное время завершения"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "показать примерное абсолютное время завершения"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "показать скорость передачи данных"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "показать среднюю скорость передачи данных"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "показать объём переданных данных в байтах"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "показать использование буфера передачи в процентах"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "КОЛ"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "показать КОЛ байт, переданных в последний раз"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "ФОРМАТ"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "указать формат вывода как ФОРМАТ"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "показать проценты вместо визуальной информации"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "не отображать никакую информацию о передаче"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "показать объём переданных данных в битах"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "считать суффиксы как умножители на 1000, а не на 1024"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "ничего не показывать, пока не будет передан первый байт"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "СЕК"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "ничего не показывать, пока не пройдёт СЕК секунд"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "РАЗМ"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "указать ожидаемый объём данных как РАЗМ байт"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "если объём неизвестен, показать скорость и макс. скорость"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "считать линии вместо байт"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "строки прерываются нулями"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "обновлять каждые СЕК секунд"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "вычислять среднюю скорость за последние СЕК секунд (по умолчанию 30)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "ШИРИНА"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "считать, что в одной строке помещается ШИРИНА символов"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "ВЫСОТА"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "считать, что на экране помещается ВЫСОТА строк"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "ИМЯ"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "писать ИМЯ до визуальной информации"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "СТИЛЬ"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "задать стиль полоски по умолчанию как СТИЛЬ"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr "НАЗНАЧ"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "дополнительно выводить прогресс в НАЗНАЧ"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "после завершения показать статистику"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "вевести, даже если стд. ошибка не является терминалом"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr ""
|
||||
"использовать символьные последовательности для позиционирования курсора"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "ФАЙЛ"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "направить вывод в ФАЙЛ вместо стд. вывода"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "СКОР"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "ограничить скорость передачи до СКОР байт/сек"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "БАЙТ"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "использовать буфер размера БАЙТ"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "использовать чтение/запись вместо splice()"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "пропустить ошибки чтения во вводе"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "пропускать ошибки в <БАЙТ> блоках за раз"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "остановить после передачи --size байт"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "сбрасывать кеш на диск каждый раз"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "использовать прямой ввод/вывод для обхода кеша"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "отбрасывать ввод вместо записи в вывод"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "записывать весь ввод в ФАЙЛ прежде, чем отправлять на вывод"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "следить за FD файла, открытого процессом ИДпр"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "ИДпр"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "обновить настройки ИДпр процесса"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr "показать прогресс процесса ИДпр"
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
"запустить команду и отслеживать её стандартный ввод, вывод или и то, и другое"
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "сохранить ИД процесса в ФАЙЛ"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "показать справку и завершить работу"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "показать версию программы и завершить работу"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "вести запись отладочного журнала в ФАЙЛ"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Использование: %s [ОПЦИИ] [ФАЙЛ]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "Поддерживаемые последовательности:"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Сообщайте о проблемах на: %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(ввод)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr "необходимо указать команду для запуска"
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "ошибка выделения памяти"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr "файлы списка не должны содержать строк, начинающихся с символа @"
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ожидался ИД процесса или пара ИДпр:ДФ"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "неправильный ИД процесса"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr "число не распознано"
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "ожидалось целое число"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "ожидалось число"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Выполните `%s --help' для получения подробностей."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Выполните `%s -h' для получения подробностей."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "удалённое управление невозможно при отслеживании дескрипторов файлов"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "передача файлов невозможна при отслеживании дескрипторов файлов"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "невозможно на системах без /proc/self/fdinfo"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Лицензия: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr "Это свободная программа. Вы можете изменять и распространять её."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
"Разработчики не дают никаких гарантий, связанных с работой этой программы, "
|
||||
"насколько это юридически возможно."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Веб-сайт проекта"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "не удалось открыть блокирующий файл"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "прервано по сигналу"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "ошибка закрытия файла"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "файл ввода также используется и для вывода"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(нет)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(стд. ввод)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr "бит/с"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr "/с"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "байт/с"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr "бит"
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "байт"
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ОЖИД"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr "ЗАВЕРШ"
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "скор. мин/сред/макс/дев"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "скорость не изменяется"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr "ИДпр"
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr "дф"
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "сообщение не получено"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "Этой системой не поддерживается SA_SIGINFO"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "внимание: замечены ошибки чтения"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "ошибка записи"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "не является обычным файлом или блочным устройством"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "не удалось получить информацию о файле"
|
||||
|
||||
#~ msgid "is a directory"
|
||||
#~ msgstr "является каталогом"
|
||||
|
||||
#~ msgid "failed to generate sysfs filename"
|
||||
#~ msgstr "не удалось создать имя файла sysfs"
|
||||
|
||||
#~ msgid "failed to read sysfs size file"
|
||||
#~ msgstr "не удалось узнать размер файла sysfs"
|
||||
|
||||
#~ msgid "failed to open block device"
|
||||
#~ msgstr "не удалось открыть блочное устройство"
|
||||
|
||||
#~ msgid "failed to determine size of block device"
|
||||
#~ msgstr "не удалось определить размер блочного устройства"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "не удалось выделить память для структуры опций"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "не удалось выделить память для структуры опций argv"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "не удалось получить имя терминала"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "попытка блокировки не удалась"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "не удалось открыть терминал"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "не удалось прочесть файл"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "не удалось получить информацию о выходном файле"
|
||||
|
||||
#~ msgid "history structure allocation failed"
|
||||
#~ msgstr "не удалось выделить память для структуры истории"
|
||||
|
||||
#~ msgid "file list allocation failed"
|
||||
#~ msgstr "не удалось выделить память для списка файлов"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "чтение не удалось"
|
||||
|
||||
#~ msgid "no transfer buffer allocated"
|
||||
#~ msgstr "не выделена память для буфера передачи"
|
||||
|
||||
#~ msgid "failed to set interval timer"
|
||||
#~ msgstr "не удалось задать измеритель временного промежутка"
|
||||
|
||||
#~ msgid "failed to clear interval timer"
|
||||
#~ msgstr "не удалось очистить измеритель временного промежутка"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "запрос выборки не удался"
|
||||
|
||||
#~ msgid "PID[:FD]"
|
||||
#~ msgstr "ИДпр[:FD]"
|
||||
@@ -0,0 +1,621 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: pv 1.8.14\n"
|
||||
"Report-Msgid-Bugs-To: https://codeberg.org/ivarch/pv/issues\n"
|
||||
"POT-Creation-Date: 2026-08-01 14:53+0100\n"
|
||||
"PO-Revision-Date: 2025-10-05 20:09+0000\n"
|
||||
"Last-Translator: Oğuz Ersen <ersen@noreply.codeberg.org>\n"
|
||||
"Language-Team: Turkish <https://translate.codeberg.org/projects/pv/pv/tr/>\n"
|
||||
"Language: tr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.13.2\n"
|
||||
|
||||
#: src/main/help.c:300
|
||||
msgid "show progress bar"
|
||||
msgstr "ilerleme çubuğunu göster"
|
||||
|
||||
#: src/main/help.c:303
|
||||
msgid "show elapsed time"
|
||||
msgstr "geçen süreyi göster"
|
||||
|
||||
#: src/main/help.c:306
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "tahmini varış (tamamlanma) zamanını göster"
|
||||
|
||||
#: src/main/help.c:309
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "mutlak tahmini varış (tamamlanma) zamanını göster"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "veri aktarım oranı sayacını göster"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "veri aktarımı ortalama hız sayacını göster"
|
||||
|
||||
#: src/main/help.c:318
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "aktarılan bayt sayısını göster"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "aktarım tamponunun kullanım yüzdesini göster"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "NUM"
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "son yazılan NUM baytlarını göster"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "çıktı formatını FORMAT olarak ayarlayın"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "görsel bilgileri değil, yüzdeleri çıktı olarak yazdır"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "hiçbir transfer bilgisini yazdırma"
|
||||
|
||||
#: src/main/help.c:337
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "aktarılan bit sayısını göster"
|
||||
|
||||
#: src/main/help.c:340
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "ekleri 1024 yerine 1000'in katları olarak değerlendir"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "ilk bayt aktarılana kadar hiçbir şey gösterme"
|
||||
|
||||
#: src/main/help.c:345 src/main/help.c:360 src/main/help.c:363
|
||||
msgid "SEC"
|
||||
msgstr "SEC"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "SEC saniye geçene kadar hiçbir şey gösterme"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "SIZE"
|
||||
msgstr "BOYUT"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "tahmini veri boyutunu BOYUT bayt olarak ayarlayın"
|
||||
|
||||
#: src/main/help.c:352
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "boyut bilinmiyorsa, oranı maksimum oranla göster"
|
||||
|
||||
#: src/main/help.c:355
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "bayt yerine satır say"
|
||||
|
||||
#: src/main/help.c:358
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "satırlar boş sonlandırılır"
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "her SEC saniyede bir güncelleme"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "geçmiş SEC saniyeleri üzerinden ortalama hızı hesapla (varsayılan 30s)"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "WIDTH"
|
||||
msgstr "GENİŞLİK"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "terminalin GENİŞLİK karakter genişliğinde olduğunu varsayalım"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "HEIGHT"
|
||||
msgstr "YÜKSEKLİK"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "terminalin YÜKSEKLİK sıraları yüksekliğinde olduğunu varsayalım"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "NAME"
|
||||
msgstr "İSİM"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "görsel bilgiyi İSİM ile öne ekle"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "STYLE"
|
||||
msgstr "BİÇİM"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "set default bar style to STYLE"
|
||||
msgstr "öntanımlı çubuk biçimini BİÇİM olarak ayarla"
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "SPEC"
|
||||
msgstr "BELİRT"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr "ilerlemeyi BELİRT ögesine de gönder"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "set terminal progress state with OSC 9;4 (ConEmu)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "transfer istatistiklerini sonda göster"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "standart hata bir terminal olmasa bile çıktı yazdır"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "imleç konumlandırma kaçış dizilerini kullan"
|
||||
|
||||
#: src/main/help.c:394 src/main/help.c:430 src/main/help.c:449
|
||||
#: src/main/help.c:459
|
||||
msgid "FILE"
|
||||
msgstr "DOSYA"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "çıktıyı stdout yerine DOSYA'ya yaz"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "RATE"
|
||||
msgstr "ORAN"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "aktarımı saniye başına ORAN bayt ile sınırlandırın"
|
||||
|
||||
#: src/main/help.c:400 src/main/help.c:406 src/main/help.c:412
|
||||
msgid "BYTES"
|
||||
msgstr "BAYTLAR"
|
||||
|
||||
#: src/main/help.c:401
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "BAYTLAR tampon boyutu kullanın"
|
||||
|
||||
#: src/main/help.c:404
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "splice() kullanma, her zaman read/write kullan"
|
||||
|
||||
#: src/main/help.c:407
|
||||
msgid "set the pipe buffer size to BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "skip read errors in input"
|
||||
msgstr "girdideki okuma hatalarını atla"
|
||||
|
||||
#: src/main/help.c:413
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "BAYTLAR blokları halinde hataları atla"
|
||||
|
||||
#: src/main/help.c:416
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "--size bayt transfer edildikten sonra dur"
|
||||
|
||||
#: src/main/help.c:419
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "her yazmadan sonra önbelleği diske boşalt"
|
||||
|
||||
#: src/main/help.c:422
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "Önbelleği atlamak için doğrudan I/O kullan"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "try to seek instead of writing null bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:428
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "Girdiyi çıktıya yazmak yerine yok say"
|
||||
|
||||
#: src/main/help.c:431
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "çıktıya yazmadan önce tüm girdiyi DOSYA'ya yaz"
|
||||
|
||||
#: src/main/help.c:434
|
||||
msgid "PID[:FD]|=NAME|@LISTFILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:435
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "FD izleme dosyası PID işlemi tarafından açıldı"
|
||||
|
||||
#: src/main/help.c:438 src/main/help.c:441
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:439
|
||||
msgid "update settings of process PID"
|
||||
msgstr "süreç PID ayarlarını güncelle"
|
||||
|
||||
#: src/main/help.c:442
|
||||
msgid "show progress of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:446
|
||||
msgid "run a command and monitor its standard input, output, or both"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:450
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "FILE'da işlem kimliğini (ID) kaydet"
|
||||
|
||||
#: src/main/help.c:453
|
||||
msgid "show this help and exit"
|
||||
msgstr "bu yardımı göster ve çık"
|
||||
|
||||
#: src/main/help.c:456
|
||||
msgid "show version information and exit"
|
||||
msgstr "sürüm bilgilerini göster ve çık"
|
||||
|
||||
#: src/main/help.c:460
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "Hata ayıklama kayıtlarını DOSYA'ya yaz"
|
||||
|
||||
#: src/main/help.c:486
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Kullanım şekli: %s [AYAR] [DOSYA]..."
|
||||
|
||||
#: src/main/help.c:497
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"İzleme ile DOSYA(lar)ı veya standart girdiyi standart çıktı ile birleştirin."
|
||||
|
||||
#: src/main/help.c:639
|
||||
msgid "Supported format sequences:"
|
||||
msgstr "Desteklenen biçim dizileri:"
|
||||
|
||||
#: src/main/help.c:653
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Lütfen hataları şu adrese bildirin: %s"
|
||||
|
||||
#: src/main/main.c:225
|
||||
msgid "(input)"
|
||||
msgstr "(giriş)"
|
||||
|
||||
#: src/main/main.c:381 src/main/options.c:1359
|
||||
msgid "a command to run must be specified"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:704 src/main/options.c:757 src/main/options.c:777
|
||||
#: src/pv/display.c:1086 src/pv/state.c:45 src/pv/state.c:902
|
||||
#: src/pv/state.c:914 src/pv/state.c:950 src/pv/transfer.c:1335
|
||||
#: src/pv/transfer.c:1451 src/pv/transfer.c:1778
|
||||
msgid "memory allocation failure"
|
||||
msgstr "bellek ayırma başarısız"
|
||||
|
||||
#: src/main/options.c:418
|
||||
msgid "list files may not contain @ lines"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:438 src/main/options.c:440 src/main/options.c:901
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "süreç kimliği (ID) veya pid:fd çifti bekleniyor"
|
||||
|
||||
#: src/main/options.c:449 src/main/options.c:451 src/main/options.c:908
|
||||
msgid "invalid process ID"
|
||||
msgstr "geçersiz süreç kimliği (ID)"
|
||||
|
||||
#: src/main/options.c:829
|
||||
msgid "numeric value not understood"
|
||||
msgstr "sayısal değer anlaşılmadı"
|
||||
|
||||
#: src/main/options.c:843
|
||||
msgid "integer argument expected"
|
||||
msgstr "tamsayı bağımsız değişkeni bekleniyor"
|
||||
|
||||
#: src/main/options.c:853
|
||||
msgid "numeric argument expected"
|
||||
msgstr "sayısal bağımsız değişken bekleniyor"
|
||||
|
||||
#: src/main/options.c:864
|
||||
msgid "missing filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:890
|
||||
msgid "missing process name"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1182
|
||||
msgid "invalid side specification"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1197
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Daha fazla bilgi için `%s --help' seçeneğini deneyin."
|
||||
|
||||
#: src/main/options.c:1199
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Daha fazla bilgi için `%s -h' seçeneğini deneyin."
|
||||
|
||||
#: src/main/options.c:1231
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"dosya tanımlayıcılarını izlerken satır modu veya aktarım değiştirici "
|
||||
"seçeneklerini kullanamaz"
|
||||
|
||||
#: src/main/options.c:1239
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr "dosya tanımlayıcılarını izlerken imleç konumlandırmayı kullanamaz"
|
||||
|
||||
#: src/main/options.c:1247
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "dosya tanımlayıcılarını izlerken uzaktan kumandayı kullanamaz"
|
||||
|
||||
#: src/main/options.c:1255
|
||||
msgid "cannot use remote query when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1263
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "dosya tanımlayıcıları izlenirken dosya aktarılamıyor"
|
||||
|
||||
#: src/main/options.c:1287
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "/proc/self/fdinfo olmayan sistemlerde kullanılamaz"
|
||||
|
||||
#: src/main/options.c:1298
|
||||
msgid "cannot use remote control and remote query together"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1325
|
||||
msgid "monitor mode cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1337
|
||||
msgid "monitor mode cannot be used with store-and-forward"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:1348
|
||||
msgid "files cannot be specified with this option"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Lisans: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
"Bu özgür bir yazılımdır: değiştirmekte ve yeniden dağıtmakta özgürsünüz."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Yasaların izin verdiği ölçüde GARANTİ YOKTUR."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Proje web sitesi"
|
||||
|
||||
#: src/pv/cursor.c:108 src/pv/cursor.c:135
|
||||
msgid "failed to open lock file"
|
||||
msgstr "lock dosyası açılamadı"
|
||||
|
||||
#: src/pv/cursor.c:790 src/pv/cursor.c:792
|
||||
msgid "interrupted by a signal"
|
||||
msgstr "bir işaret tarafından kesildi"
|
||||
|
||||
#: src/pv/display.c:311
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:329
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/file.c:81
|
||||
msgid "/dev/null is not usable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:371
|
||||
msgid "error closing file"
|
||||
msgstr "dosya kapatılırken hata"
|
||||
|
||||
#: src/pv/file.c:438
|
||||
msgid "input file is also the output"
|
||||
msgstr "girdi dosyası aynı zamanda çıkış"
|
||||
|
||||
#: src/pv/file.c:596
|
||||
msgid "(none)"
|
||||
msgstr "(yok)"
|
||||
|
||||
#: src/pv/file.c:598
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/format/averagerate.c:34 src/pv/format/progressbar.c:92
|
||||
#: src/pv/format/rate.c:36 src/pv/loop.c:181
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/format/averagerate.c:38 src/pv/format/progressbar.c:96
|
||||
#: src/pv/format/rate.c:40 src/pv/loop.c:181
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/format/bytes.c:35
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/format/bytes.c:39 src/pv/transfer.c:1284
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/format/eta.c:63 src/pv/format/eta.c:67
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/format/fineta.c:93
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/loop.c:180
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "oran min/ortalama/maks/standart sapma"
|
||||
|
||||
#: src/pv/loop.c:192
|
||||
msgid "rate not measured"
|
||||
msgstr "oran ölçülmedi"
|
||||
|
||||
#: src/pv/loop.c:1098 src/pv/loop.c:1114 src/pv/loop.c:1132 src/pv/remote.c:93
|
||||
#: src/pv/remote.c:188 src/pv/remote.c:536 src/pv/remote.c:582
|
||||
#: src/pv/watchpid.c:123 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:158 src/pv/watchpid.c:194
|
||||
#: src/pv/watchpid.c:206 src/pv/watchpid.c:218 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:286 src/pv/watchpid.c:401
|
||||
#: src/pv/watchpid.c:409 src/pv/watchpid.c:556 src/pv/watchpid.c:565
|
||||
#: src/pv/watchpid.c:586
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/loop.c:1132 src/pv/watchpid.c:132 src/pv/watchpid.c:142
|
||||
#: src/pv/watchpid.c:151 src/pv/watchpid.c:160 src/pv/watchpid.c:268
|
||||
#: src/pv/watchpid.c:277 src/pv/watchpid.c:288
|
||||
msgid "fd"
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/remote.c:242 src/pv/remote.c:636
|
||||
msgid "message not received"
|
||||
msgstr "mesaj alınamadı"
|
||||
|
||||
#: src/pv/remote.c:659 src/pv/remote.c:677
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO bu sistemde desteklenmiyor"
|
||||
|
||||
#: src/pv/transfer.c:1173
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "uyarı: okuma hataları tespit edildi"
|
||||
|
||||
#: src/pv/transfer.c:1283
|
||||
msgid "skipped past read error"
|
||||
msgstr "geçmiş okuma hatası atlandı"
|
||||
|
||||
#: src/pv/transfer.c:1642
|
||||
msgid "write error"
|
||||
msgstr "yazma hatası"
|
||||
|
||||
#: src/pv/watchpid.c:160 src/pv/watchpid.c:288
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "normal bir dosya veya blok aygıtı değil"
|
||||
|
||||
#~ msgid "state allocation failed"
|
||||
#~ msgstr "durum tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "failed to stat file"
|
||||
#~ msgstr "dosya statüsünde başarısız oldu"
|
||||
|
||||
#~ msgid "is a directory"
|
||||
#~ msgstr "bir dizindir"
|
||||
|
||||
#~ msgid "failed to generate sysfs filename"
|
||||
#~ msgstr "sysfs dosya adı oluşturulamadı"
|
||||
|
||||
#~ msgid "failed to read sysfs size file"
|
||||
#~ msgstr "sysfs boyut dosyası okunamadı"
|
||||
|
||||
#~ msgid "failed to open block device"
|
||||
#~ msgstr "blok aygıtı açılamadı"
|
||||
|
||||
#~ msgid "failed to determine size of block device"
|
||||
#~ msgstr "blok aygıtının boyutu belirlenemedi"
|
||||
|
||||
#~ msgid "option structure allocation failed"
|
||||
#~ msgstr "seçenek yapısı tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "option structure argv allocation failed"
|
||||
#~ msgstr "seçenek yapısı argv tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "failed to get terminal name"
|
||||
#~ msgstr "terminal adı alınamadı"
|
||||
|
||||
#~ msgid "lock attempt failed"
|
||||
#~ msgstr "kilit denemesi başarısız oldu"
|
||||
|
||||
#~ msgid "failed to open terminal"
|
||||
#~ msgstr "terminal açılamadı"
|
||||
|
||||
#~ msgid "failed to seek to start of output"
|
||||
#~ msgstr "çıktının başlangıcına ulaşılamadı"
|
||||
|
||||
#~ msgid "failed to read file"
|
||||
#~ msgstr "dosya okunamadı"
|
||||
|
||||
#~ msgid "failed to stat output file"
|
||||
#~ msgstr "çıktı dosyası stat edilemedi"
|
||||
|
||||
#~ msgid "history structure allocation failed"
|
||||
#~ msgstr "geçmiş yapısı tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "file list allocation failed"
|
||||
#~ msgstr "dosya listesi tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "read failed"
|
||||
#~ msgstr "okuma başarısız"
|
||||
|
||||
#~ msgid "file is not seekable"
|
||||
#~ msgstr "dosya aranabilir değil"
|
||||
|
||||
#~ msgid "failed to seek past error"
|
||||
#~ msgstr "geçmiş hatayı aramakta başarısız oldu"
|
||||
|
||||
#~ msgid "no transfer buffer allocated"
|
||||
#~ msgstr "aktarım arabelleği ayrılmamış"
|
||||
|
||||
#~ msgid "failed to set interval timer"
|
||||
#~ msgstr "aralık zamanlayıcısı ayarlanamadı"
|
||||
|
||||
#~ msgid "failed to clear interval timer"
|
||||
#~ msgstr "aralık zamanlayıcısı temizlenemedi"
|
||||
|
||||
#~ msgid "line position buffer allocation failed"
|
||||
#~ msgstr "satır konumu arabellek tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "select call failed"
|
||||
#~ msgstr "seçme çağrısı başarısız oldu"
|
||||
|
||||
#~ msgid "process list allocation failed"
|
||||
#~ msgstr "işlem listesi tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "file descriptor list allocation failed"
|
||||
#~ msgstr "dosya tanımlayıcı listesi tahsisi başarısız oldu"
|
||||
|
||||
#~ msgid "PID[:FD]"
|
||||
#~ msgstr "PID[:FD]"
|
||||
@@ -0,0 +1 @@
|
||||
config.h.in
|
||||
+33
-10
@@ -3,23 +3,25 @@
|
||||
* `configure' script. Include this after config.h and before anything
|
||||
* else.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
# include "library/gettext.h"
|
||||
#if ENABLE_NLS
|
||||
# ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# endif
|
||||
# ifdef HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
# endif
|
||||
# define _(String) gettext (String)
|
||||
# define N_(String) (String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
# define N_(String) (String)
|
||||
#endif
|
||||
|
||||
#undef HAVE_IPC
|
||||
#ifdef HAVE_SYS_IPC_H
|
||||
#define HAVE_IPC 1
|
||||
#endif
|
||||
|
||||
#undef CURSOR_ANSWERBACK_BYTE_BY_BYTE
|
||||
#ifndef _AIX
|
||||
#define CURSOR_ANSWERBACK_BYTE_BY_BYTE 1
|
||||
@@ -42,4 +44,25 @@ typedef bool _Bool;
|
||||
# define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
/* Whether "--remote" and "--query" should be available. */
|
||||
#undef PV_REMOTE_CONTROL
|
||||
#if HAVE_DECL_SA_SIGINFO
|
||||
# if SIGINFO_PROVIDES_PID
|
||||
#define PV_REMOTE_CONTROL 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SPLINT
|
||||
/* Remove __attribute__(()) if not using GCC. */
|
||||
#ifndef __GNUC__
|
||||
#define __attribute__(x) /* GCC-only feature */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Support for the fallthrough attribute is not universal. */
|
||||
/* From https://stackoverflow.com/questions/45349079/how-to-use-attribute-fallthrough-correctly-in-gcc */
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#define FALL_THROUGH __attribute__ ((fallthrough))
|
||||
#else
|
||||
#define FALL_THROUGH /*@-noeffect@*/ ((void)0) /*@+noeffect@*/
|
||||
#endif /* __GNUC__ >= 7 */
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Replacement getopt function's header file. Include this AFTER config.h.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRARY_GETOPT_H
|
||||
#define _LIBRARY_GETOPT_H 1
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETOPT
|
||||
|
||||
int minigetopt(int, char **, char *);
|
||||
extern char *minioptarg;
|
||||
extern int minioptind, miniopterr, minioptopt;
|
||||
|
||||
#define getopt minigetopt /* Flawfinder: ignore */
|
||||
#define optarg minioptarg
|
||||
#define optind minioptind
|
||||
#define opterr miniopterr
|
||||
#define optopt minioptopt
|
||||
|
||||
#endif /* !HAVE_GETOPT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBRARY_GETOPT_H */
|
||||
|
||||
/* EOF */
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Replacement gettext library header file. Include this within config.h,
|
||||
* like this:
|
||||
*
|
||||
* #ifdef ENABLE_NLS
|
||||
* # include "library/gettext.h"
|
||||
* #else
|
||||
* # define _(String) (String)
|
||||
* # define N_(String) (String)
|
||||
* #endif
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRARY_GETTEXT_H
|
||||
#define _LIBRARY_GETTEXT_H 1
|
||||
|
||||
#ifdef HAVE_GETTEXT
|
||||
# ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# endif
|
||||
# ifdef HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
# endif
|
||||
# define _(String) gettext (String)
|
||||
# define N_(String) (String)
|
||||
#else
|
||||
# define _(String) minigettext (String)
|
||||
# define N_(String) (String)
|
||||
# ifdef HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
# else
|
||||
# define setlocale minisetlocale
|
||||
# ifndef LC_ALL
|
||||
# define LC_ALL ""
|
||||
# endif
|
||||
# endif
|
||||
# define bindtextdomain minibindtextdomain
|
||||
# define textdomain minitextdomain
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *minisetlocale(const char *, const char *);
|
||||
char *minibindtextdomain(const char *, const char *);
|
||||
char *minitextdomain(const char *);
|
||||
char *minigettext(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBRARY_GETTEXT_H */
|
||||
|
||||
/* EOF */
|
||||
+90
-29
@@ -1,14 +1,21 @@
|
||||
/*
|
||||
* Global program option structure and the parsing function prototype.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#ifndef _OPTIONS_H
|
||||
#define _OPTIONS_H 1
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -16,9 +23,70 @@ extern "C" {
|
||||
struct opts_s;
|
||||
typedef struct opts_s *opts_t;
|
||||
|
||||
struct opts_s { /* structure describing run-time options */
|
||||
char *program_name; /* name the program is running as */
|
||||
bool do_nothing; /* exit-without-doing-anything flag */
|
||||
/*
|
||||
* Overall program actions to select.
|
||||
*/
|
||||
typedef enum {
|
||||
PV_ACTION_NOTHING, /* do nothing, and exit */
|
||||
PV_ACTION_TRANSFER, /* transfer data */
|
||||
PV_ACTION_STORE_AND_FORWARD, /* store to file, then output from it */
|
||||
PV_ACTION_WATCHFD, /* watch process file descriptors */
|
||||
PV_ACTION_REMOTE_CONTROL, /* remotely control another pv */
|
||||
PV_ACTION_QUERY, /* watch the state of another pv */
|
||||
PV_ACTION_MONITOR /* run a process, watch its stdin/out */
|
||||
} pvaction_t;
|
||||
|
||||
/*
|
||||
* Sides of a monitored command to monitor with PV_ACTION_MONITOR.
|
||||
*/
|
||||
typedef enum {
|
||||
PV_SIDE_NONE, /* don't monitor a command */
|
||||
PV_SIDE_IN, /* monitor only the input side */
|
||||
PV_SIDE_OUT, /* monitor only the output side */
|
||||
PV_SIDE_BOTH /* monitor both sides */
|
||||
} pvside_t;
|
||||
|
||||
typedef /*@null@*/ const char * argv_string;
|
||||
|
||||
/*
|
||||
* Structure describing run-time options.
|
||||
*
|
||||
* Members are ordered by size to minimise padding.
|
||||
*/
|
||||
struct opts_s {
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
/*@keep@*/ const char *program_name; /* name the program is running as */
|
||||
/*@keep@*/ /*@null@*/ char *output; /* fd to write output to */
|
||||
/*@keep@*/ /*@null@*/ char *name; /* display name, if any */
|
||||
/*@keep@*/ /*@null@*/ char *name1; /* first name, if two were given */
|
||||
/*@keep@*/ /*@null@*/ char *default_bar_style; /* default bar style */
|
||||
/*@keep@*/ /*@null@*/ char *format; /* output format, if any */
|
||||
/*@keep@*/ /*@null@*/ char *format1; /* first format, if two were given */
|
||||
/*@keep@*/ /*@null@*/ char *pidfile; /* PID file, if any */
|
||||
/*@keep@*/ /*@null@*/ char *store_and_forward_file; /* store and forward file, if any */
|
||||
/*@keep@*/ /*@null@*/ char *extra_display; /* extra display specifier, if any */
|
||||
/*@keep@*/ /*@null@*/ pid_t *watchfd_pid; /* array of processes to watch fds of */
|
||||
/*@keep@*/ /*@null@*/ int *watchfd_fd; /* array of fds to watch in each one (0=all) */
|
||||
/*@keep@*/ /*@null@*/ argv_string *argv; /* array of non-option arguments */
|
||||
size_t lastwritten; /* show N bytes last written */
|
||||
long double rate_limit; /* rate limit, in bytes per second */
|
||||
size_t buffer_size; /* buffer size, in bytes (0=default) */
|
||||
size_t pipe_buffer_size; /* pipe buffer size, in bytes (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
pid_t remote; /* PID of pv to update settings of */
|
||||
pid_t query; /* PID of pv to query progress of */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
unsigned int argc; /* number of non-option arguments */
|
||||
unsigned int argv_length; /* allocated array size for non-option arguments */
|
||||
unsigned int watchfd_count; /* number of watchfd items */
|
||||
unsigned int watchfd_length; /* allocated watchfd item array size */
|
||||
pvaction_t action; /* the program action to perform */
|
||||
pvside_t side; /* which side of the monitored command to monitor */
|
||||
bool progress; /* progress bar flag */
|
||||
bool timer; /* timer flag */
|
||||
bool eta; /* ETA flag */
|
||||
@@ -27,46 +95,39 @@ struct opts_s { /* structure describing run-time options */
|
||||
bool average_rate; /* average rate counter flag */
|
||||
bool bytes; /* bytes transferred flag */
|
||||
bool bits; /* report transfer size in bits */
|
||||
bool decimal_units; /* decimal prefix flag */
|
||||
bool bufpercent; /* transfer buffer percentage flag */
|
||||
unsigned int lastwritten; /* show N bytes last written */
|
||||
bool force; /* force-if-not-terminal flag */
|
||||
bool cursor; /* whether to use cursor positioning */
|
||||
bool numeric; /* numeric output only */
|
||||
bool wait; /* wait for transfer before display */
|
||||
bool rate_gauge; /* if size unknown, show rate vs max rate */
|
||||
bool linemode; /* count lines instead of bytes */
|
||||
bool null; /* lines are null-terminated */
|
||||
bool no_op; /* do nothing other than pipe data */
|
||||
unsigned long long rate_limit; /* rate limit, in bytes per second */
|
||||
unsigned long long buffer_size;/* buffer size, in bytes (0=default) */
|
||||
unsigned int remote; /* PID of pv to update settings of */
|
||||
unsigned long long size; /* total size of data */
|
||||
bool null_terminated_lines; /* lines are null-terminated */
|
||||
bool no_display; /* do nothing other than pipe data */
|
||||
bool no_splice; /* flag set if never to use splice */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
unsigned int watch_pid; /* process to watch fds of */
|
||||
int watch_fd; /* fd to watch */
|
||||
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
char *name; /* process name, if any */
|
||||
char *format; /* output format, if any */
|
||||
char *pidfile; /* PID file, if any */
|
||||
int argc; /* number of non-option arguments */
|
||||
char **argv; /* array of non-option arguments */
|
||||
bool sparse_output; /* set if we leave holes in the output */
|
||||
bool discard_input; /* set to write nothing to output */
|
||||
bool use_osc94; /* set to enable OSC 9;4 sequences */
|
||||
bool show_stats; /* set to write statistics at the end */
|
||||
bool width_set_manually; /* width was set manually, not detected */
|
||||
bool height_set_manually; /* height was set manually, not detected */
|
||||
bool rate_limit_specified; /* whether a rate limit value was given */
|
||||
bool rate_limit_active; /* whether rate limiting is in effect (>0) */
|
||||
};
|
||||
|
||||
extern opts_t opts_parse(int, char **);
|
||||
extern void opts_free(opts_t);
|
||||
/*@-exportlocal@*/
|
||||
/* splint thinks opts_free is exported but not used - it is used. */
|
||||
|
||||
extern /*@null@*/ /*@only@*/ opts_t opts_parse(unsigned int, char **);
|
||||
extern void opts_free(/*@only@*/ opts_t);
|
||||
extern bool opts_add_file(opts_t, const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OPTIONS_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+595
-205
@@ -1,16 +1,20 @@
|
||||
/*
|
||||
* Functions internal to the PV library. Include "config.h" first.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#ifndef _PV_INTERNAL_H
|
||||
#define _PV_INTERNAL_H 1
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -19,179 +23,394 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PV_DISPLAY_PROGRESS 1
|
||||
#define PV_DISPLAY_TIMER 2
|
||||
#define PV_DISPLAY_ETA 4
|
||||
#define PV_DISPLAY_RATE 8
|
||||
#define PV_DISPLAY_AVERAGERATE 16
|
||||
#define PV_DISPLAY_BYTES 32
|
||||
#define PV_DISPLAY_NAME 64
|
||||
#define PV_DISPLAY_BUFPERCENT 128
|
||||
#define PV_DISPLAY_OUTPUTBUF 256
|
||||
#define PV_DISPLAY_FINETA 512
|
||||
|
||||
#define RATE_GRANULARITY 100000 /* usec between -L rate chunks */
|
||||
#define RATE_BURST_WINDOW 5 /* rate burst window (multiples of rate) */
|
||||
#define REMOTE_INTERVAL 100000 /* usec between checks for -R */
|
||||
#define BUFFER_SIZE 409600 /* default transfer buffer size */
|
||||
#define BUFFER_SIZE_MAX 524288 /* max auto transfer buffer size */
|
||||
#define MAX_READ_AT_ONCE 524288 /* max to read() in one go */
|
||||
#define MAX_WRITE_AT_ONCE 524288 /* max to write() in one go */
|
||||
#define TRANSFER_READ_TIMEOUT 90000 /* usec to time reads out at */
|
||||
#define TRANSFER_WRITE_TIMEOUT 900000 /* usec to time writes out at */
|
||||
#define RATE_GRANULARITY 100000000 /* nsec between -L rate chunks */
|
||||
#define RATE_BURST_WINDOW 5.0 /* rate burst window (multiples of rate) */
|
||||
#define REMOTE_INTERVAL 100000000 /* nsec between checks for -R and -Q */
|
||||
#define MONITOR_EXCHANGE_INTERVAL 100000000 /* nsec between "-M both" data exchanges */
|
||||
#define BUFFER_SIZE (size_t) 409600 /* default transfer buffer size */
|
||||
#define BUFFER_SIZE_MAX (size_t) 524288 /* max auto transfer buffer size */
|
||||
#define MAX_READ_AT_ONCE (size_t) 524288 /* max to read() in one go */
|
||||
#define MAX_WRITE_AT_ONCE (size_t) 524288 /* max to write() in one go */
|
||||
#define MAX_SPLICE_AT_ONCE 1048576 /* max to splice() in one go */
|
||||
#define MAX_CFR_AT_ONCE 1073741824 /* max to copy_file_range() in one go */
|
||||
#define TRANSFER_READ_TIMEOUT 0.09L /* seconds to time reads out at */
|
||||
#define TRANSFER_WRITE_TIMEOUT 0.9L /* seconds to time writes out at */
|
||||
#define MAX_LINE_POSITIONS 100000 /* number of lines to remember positions of */
|
||||
|
||||
/*
|
||||
* Whether to always try to use the whole transfer buffer, reducing the
|
||||
* number of reads and writes at the expense of moving bytes around.
|
||||
*/
|
||||
#define MAXIMISE_BUFFER_FILL 1
|
||||
|
||||
|
||||
typedef struct pvhistory {
|
||||
long long total_bytes;
|
||||
long double elapsed_sec;
|
||||
} pvhistory_t;
|
||||
/* Sizes for various statically sized buffers. */
|
||||
|
||||
#define PV_SIZEOF_DEFAULT_FORMAT 512
|
||||
#define PV_SIZEOF_CWD 4096
|
||||
#define PV_SIZEOF_LASTOUTPUT_BUFFER 256
|
||||
#define PV_SIZEOF_STR_NAME 512
|
||||
#define PV_SIZEOF_STR_TRANSFERRED 128
|
||||
#define PV_SIZEOF_STR_BUFPERCENT 128
|
||||
#define PV_SIZEOF_STR_TIMER 128
|
||||
#define PV_SIZEOF_STR_RATE 128
|
||||
#define PV_SIZEOF_STR_AVERAGE_RATE 128
|
||||
#define PV_SIZEOF_STR_PROGRESS 1024
|
||||
#define PV_SIZEOF_STR_LASTOUTPUT 512
|
||||
#define PV_SIZEOF_STR_ETA 128
|
||||
#define PV_SIZEOF_STR_FINETA 128
|
||||
#define PV_SIZEOF_LASTWRITTEN_BUFFER 256
|
||||
#define PV_SIZEOF_PREVLINE_BUFFER 1024
|
||||
#define PV_FORMAT_ARRAY_MAX 100
|
||||
#define PV_SIZEOF_CRS_LOCK_FILE 1024
|
||||
|
||||
#define PV_SIZEOF_FILE_FDINFO 4096
|
||||
#define PV_SIZEOF_FILE_FD 4096
|
||||
#define PV_SIZEOF_FILE_FDPATH 4096
|
||||
#define PV_SIZEOF_FORMAT_SEGMENTS_BUF 4096
|
||||
#define PV_SIZEOF_DISPLAY_NAME 512
|
||||
|
||||
#define PV_BARSTYLE_MAX 4 /* number of different styles allowed in a format */
|
||||
#define PV_BARSTYLE_SIZEOF_STRING 10 /* max length of a bar constituent component in bytes */
|
||||
#define PV_BARSTYLE_MAX_FILLERS 10 /* max number of bar filler strings */
|
||||
|
||||
/* Bit values for the extra displays bitmap. */
|
||||
|
||||
#define PV_DISPLAY_WINDOWTITLE 1
|
||||
#define PV_DISPLAY_PROCESSTITLE 2
|
||||
|
||||
|
||||
/*
|
||||
* Structure for data shared between multiple "pv -c" instances.
|
||||
*/
|
||||
struct pvipccursorstate_s {
|
||||
int y_topmost; /* terminal row of topmost "pv" instance */
|
||||
bool tty_tostop_added; /* whether any instance had to set TOSTOP on the terminal */
|
||||
bool tty_echoctl_cleared; /* whether any instance had to clear ECHOCTL on the terminal */
|
||||
};
|
||||
|
||||
/*
|
||||
* Types of transfer count - bytes, decimal bytes or lines.
|
||||
*/
|
||||
typedef enum {
|
||||
PV_TRANSFERCOUNT_BYTES,
|
||||
PV_TRANSFERCOUNT_DECBYTES,
|
||||
PV_TRANSFERCOUNT_LINES
|
||||
} pvtransfercount_t;
|
||||
|
||||
/* Methods used to transfer bytes from input to output. */
|
||||
typedef enum {
|
||||
PV_TRANSFERMETHOD_READWRITE, /* read() + write() */
|
||||
PV_TRANSFERMETHOD_SPLICE, /* splice() */
|
||||
PV_TRANSFERMETHOD_SPLICE_INTERMEDIATE, /* splice() through an intermediate input pipe */
|
||||
PV_TRANSFERMETHOD_COPY_FILE_RANGE, /* copy_file_range() */
|
||||
PV_TRANSFERMETHOD__UNSET
|
||||
} pvtransfermethod_t;
|
||||
|
||||
/*
|
||||
* Structure describing a short string used as part of a progress bar, whose
|
||||
* width in display characters may not be the same as its length in bytes.
|
||||
*/
|
||||
struct pvbarstring_spec_s {
|
||||
char string[PV_BARSTYLE_SIZEOF_STRING];
|
||||
uint8_t width;
|
||||
uint8_t bytes;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure describing a style of progress bar.
|
||||
*
|
||||
* The part that moves back and forth when the size isn't known, such as
|
||||
* "<=>", is "indicator".
|
||||
*
|
||||
* The string used to populate the rest of the bar is one of "filler", which
|
||||
* contains "filler_entries" array items. The first item "filler[0]" is
|
||||
* used for an empty part such as " ". The last item
|
||||
* "filler[filler_entries-1]" is used for a 100% full part, such as "=".
|
||||
*
|
||||
* If there are more than the minimum of 2 entries, then the intervening
|
||||
* entries are used for partial fills.
|
||||
*
|
||||
* When there are only 2 entries and the bar isn't completely empty or full,
|
||||
* the last filled portion of the bar is filled with "tip" instead of the
|
||||
* last filler item to indicate the tip of the bar, such as ">".
|
||||
*
|
||||
* Note that only the indicator is expected to ever be wider than 1 display
|
||||
* character. All other items are expected to have a width of 0 or 1.
|
||||
*
|
||||
* The "style_id" is an opaque identifier that should only be used to
|
||||
* determine whether two styles are the same. It is always nonzero.
|
||||
*/
|
||||
struct pvbarstyle_s {
|
||||
uint8_t style_id;
|
||||
uint8_t filler_entries;
|
||||
struct pvbarstring_spec_s indicator;
|
||||
struct pvbarstring_spec_s tip;
|
||||
struct pvbarstring_spec_s filler[PV_BARSTYLE_MAX_FILLERS];
|
||||
};
|
||||
typedef struct pvbarstyle_s *pvbarstyle_t;
|
||||
|
||||
|
||||
/* Display format component type, -1 for static string. */
|
||||
typedef int8_t pvdisplay_component_t;
|
||||
#define PVDISPLAY_COMPONENT_MAX (127) /* INT8_MAX */
|
||||
|
||||
/* Byte count of a part of the display. */
|
||||
typedef uint16_t pvdisplay_bytecount_t;
|
||||
#define PVDISPLAY_BYTECOUNT_MAX (65535) /* UINT16_MAX */
|
||||
|
||||
/* Width of a part of the display. */
|
||||
typedef uint16_t pvdisplay_width_t;
|
||||
#define PVDISPLAY_WIDTH_MAX (65535) /* UINT16_MAX */
|
||||
|
||||
/*
|
||||
* Structure defining the current state of a single watched file descriptor.
|
||||
*/
|
||||
struct pvwatchfd_s;
|
||||
typedef /*@null@*/ struct pvwatchfd_s *pvwatchfd_t;
|
||||
|
||||
/* String pointer, that is the only pointer to this resource, that can be null. */
|
||||
typedef /*@only@*/ /*@null@*/ char * nullable_only_string_t;
|
||||
|
||||
/*
|
||||
* Structure for holding PV internal state. Opaque outside the PV library.
|
||||
*
|
||||
* In general, members are ordered by size, to minimise padding.
|
||||
*/
|
||||
struct pvstate_s {
|
||||
/******************
|
||||
* Program status *
|
||||
******************/
|
||||
struct pvprogramstatus_s {
|
||||
nullable_only_string_t cwd; /* for relative paths in --watchfd */
|
||||
int current_input_file; /* index of current file being read */
|
||||
int exit_status; /* exit status to give (0=OK) */
|
||||
bool terminal_supports_utf8; /* whether the terminal supports UTF-8 */
|
||||
bool terminal_supports_colour; /* whether the terminal supports colour */
|
||||
bool checked_colour_support; /* whether we have checked colour support yet */
|
||||
bool current_input_is_pipe; /* whether the current input file is a pipe */
|
||||
bool current_input_is_file; /* whether the current input is a regular file */
|
||||
bool output_is_pipe; /* whether the output is a pipe */
|
||||
bool output_is_file; /* whether the output is a regular file */
|
||||
} status;
|
||||
|
||||
/***************
|
||||
* Input files *
|
||||
***************/
|
||||
int input_file_count; /* number of input files */
|
||||
const char **input_files; /* input files (0=first) */
|
||||
struct pvinputfiles_s {
|
||||
/*@only@*/ /*@null@*/ nullable_only_string_t *filename; /* input filenames */
|
||||
unsigned int file_count; /* number of input files */
|
||||
} files;
|
||||
|
||||
/*********************************
|
||||
* Items to watch with --watchfd *
|
||||
*********************************/
|
||||
struct {
|
||||
/*@only@*/ /*@null@*/
|
||||
struct pvwatcheditem_s { /* array of PID or PID:FD items */
|
||||
pid_t pid; /* watched PID */
|
||||
int fd; /* watched fd, or -1 for all */
|
||||
pvwatchfd_t info_array; /* watch information for each fd */
|
||||
int array_length; /* length of watch info array */
|
||||
bool finished; /* "PID:FD": fd closed; or PID gone */
|
||||
} *watching;
|
||||
unsigned int count; /* number of items in these arrays */
|
||||
bool multiple_pids; /* true if more than one distinct PID */
|
||||
} watchfd;
|
||||
|
||||
/*******************
|
||||
* Program control *
|
||||
*******************/
|
||||
bool force; /* display even if not on terminal */
|
||||
bool cursor; /* use cursor positioning */
|
||||
bool numeric; /* numeric output only */
|
||||
bool wait; /* wait for data before display */
|
||||
bool linemode; /* count lines instead of bytes */
|
||||
bool bits; /* report bits instead of bytes */
|
||||
bool null; /* lines are null-terminated */
|
||||
bool no_op; /* do nothing other than pipe data */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
bool direct_io_changed; /* set when direct_io is changed */
|
||||
bool no_splice; /* never use splice() */
|
||||
unsigned long long rate_limit; /* rate limit, in bytes per second */
|
||||
unsigned long long target_buffer_size; /* buffer size (0=default) */
|
||||
unsigned long long size; /* total size of data */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
unsigned int watch_pid; /* process to watch fds of */
|
||||
int watch_fd; /* fd to watch */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
const char *name; /* display name */
|
||||
char default_format[PV_SIZEOF_DEFAULT_FORMAT]; /* default format string */
|
||||
const char *format_string; /* output format string */
|
||||
|
||||
/******************
|
||||
* Program status *
|
||||
******************/
|
||||
const char *program_name; /* program name for error reporting */
|
||||
char cwd[PV_SIZEOF_CWD]; /* current working directory for relative path */
|
||||
const char *current_file; /* current file being read */
|
||||
int exit_status; /* exit status to give (0=OK) */
|
||||
struct pvcontrol_s {
|
||||
char default_format[PV_SIZEOF_DEFAULT_FORMAT]; /* default format string */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
/*@only@*/ /*@null@*/ char *name; /* display name */
|
||||
/*@only@*/ /*@null@*/ char *format_string; /* output format string */
|
||||
/*@only@*/ /*@null@*/ char *extra_display_spec; /* full spec for extra displays */
|
||||
/*@only@*/ /*@null@*/ char *extra_format_string; /* extra format string alone */
|
||||
/*@null@*/ char *output_name; /* name of the output, for diagnostics */
|
||||
/*@null@*/ char *default_bar_style; /* which bar style to use by default */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
long double rate_limit; /* rate limit, in bytes per second */
|
||||
size_t target_buffer_size; /* transfer buffer size (0=default) */
|
||||
size_t pipe_buffer_size; /* pipe buffer size (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
int output_fd; /* fd to write output to */
|
||||
pid_t othermonitor_pid; /* pid of the other monitor, in "-M both" mode */
|
||||
int othermonitor_read_fd; /* fd to read transfer counts from other monitor */
|
||||
int othermonitor_write_fd; /* fd to write transfer counts to other monitor */
|
||||
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
|
||||
unsigned int history_interval; /* seconds between each average rate calc history entry */
|
||||
pvdisplay_width_t width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
unsigned int extra_displays; /* bitmask of extra display destinations */
|
||||
pvformatoptions_s format_option; /* non "--format" format options (used by -R) */
|
||||
bool force; /* display even if not on terminal */
|
||||
bool cursor; /* use cursor positioning */
|
||||
bool numeric; /* numeric output only */
|
||||
bool wait; /* wait for data before display */
|
||||
bool rate_gauge; /* if size unknown, show rate vs max rate */
|
||||
bool linemode; /* count lines instead of bytes */
|
||||
bool bits; /* report bits instead of bytes */
|
||||
bool decimal_units; /* use decimal prefixes */
|
||||
bool null_terminated_lines; /* lines are null-terminated */
|
||||
bool no_display; /* do nothing other than pipe data */
|
||||
bool no_splice; /* never use splice() */
|
||||
bool stop_at_size; /* transfer is to stop at "size" bytes */
|
||||
bool sync_after_write; /* sync after every write */
|
||||
bool direct_io; /* use O_DIRECT */
|
||||
bool direct_io_changed; /* set when direct_io is changed mid-transfer */
|
||||
bool sparse_output; /* convert runs of null bytes into holes */
|
||||
bool discard_input; /* write nothing to stdout */
|
||||
bool show_stats; /* show statistics on exit */
|
||||
bool use_osc94; /* enable OSC 9;4 sequences */
|
||||
bool width_set_manually; /* width was set manually, not detected */
|
||||
bool height_set_manually; /* height was set manually, not detected */
|
||||
bool rate_limit_specified; /* whether a rate limit value was given */
|
||||
bool rate_limit_active; /* whether a rate limit is in effect (>0) */
|
||||
} control;
|
||||
|
||||
/*******************
|
||||
* Signal handling *
|
||||
*******************/
|
||||
int pv_sig_old_stderr; /* see pv_sig_ttou() */
|
||||
struct timeval pv_sig_tstp_time; /* see pv_sig_tstp() / __cont() */
|
||||
struct timeval pv_sig_toffset; /* total time spent stopped */
|
||||
volatile sig_atomic_t pv_sig_newsize; /* whether we need to get term size again */
|
||||
volatile sig_atomic_t pv_sig_abort; /* whether we need to abort right now */
|
||||
volatile sig_atomic_t reparse_display; /* whether to re-check format string */
|
||||
struct sigaction pv_sig_old_sigpipe;
|
||||
struct sigaction pv_sig_old_sigttou;
|
||||
struct sigaction pv_sig_old_sigtstp;
|
||||
struct sigaction pv_sig_old_sigcont;
|
||||
struct sigaction pv_sig_old_sigwinch;
|
||||
struct sigaction pv_sig_old_sigint;
|
||||
struct sigaction pv_sig_old_sighup;
|
||||
struct sigaction pv_sig_old_sigterm;
|
||||
struct pvsignal_s {
|
||||
/* old signal handlers to restore in pv_sig_fini(). */
|
||||
struct sigaction old_sigpipe;
|
||||
struct sigaction old_sigttou;
|
||||
struct sigaction old_sigtstp;
|
||||
struct sigaction old_sigcont;
|
||||
struct sigaction old_sigwinch;
|
||||
struct sigaction old_sigint;
|
||||
struct sigaction old_sighup;
|
||||
struct sigaction old_sigterm;
|
||||
#ifdef PV_REMOTE_CONTROL
|
||||
struct sigaction old_sigusr2;
|
||||
struct sigaction old_sigusr1;
|
||||
#endif
|
||||
struct sigaction old_sigalrm;
|
||||
struct timespec when_tstp_arrived; /* see pv_sig_tstp() / __cont() */
|
||||
struct timespec total_stoppage_time; /* total time spent stopped */
|
||||
#ifdef PV_REMOTE_CONTROL
|
||||
volatile sig_atomic_t rxusr2; /* whether SIGUSR2 was received */
|
||||
volatile pid_t sender_usr2; /* PID of sending process for SIGUSR2 */
|
||||
volatile sig_atomic_t rxusr1; /* whether SIGUSR1 was received */
|
||||
volatile pid_t sender_usr1; /* PID of sending process for SIGUSR1 */
|
||||
#endif
|
||||
} signal;
|
||||
|
||||
/*******************
|
||||
* Transient flags *
|
||||
*******************/
|
||||
struct pvtransientflags_s {
|
||||
volatile sig_atomic_t reparse_display; /* whether to re-check format string */
|
||||
volatile sig_atomic_t terminal_resized; /* whether terminal size needs re-reading */
|
||||
volatile sig_atomic_t trigger_exit; /* whether an immediate abort is required */
|
||||
volatile sig_atomic_t terminating_signal; /* signal number that triggered an exit */
|
||||
volatile sig_atomic_t clear_tty_tostop_on_exit; /* whether to clear tty TOSTOP on exit */
|
||||
volatile sig_atomic_t set_tty_echoctl_on_exit; /* whether to set tty ECHOCTL on exit */
|
||||
volatile sig_atomic_t suspend_stderr; /* whether writing to stderr is suspended */
|
||||
volatile sig_atomic_t skip_next_sigcont; /* whether to ignore the next SIGCONT */
|
||||
volatile sig_atomic_t pipe_closed; /* whether the output pipe was closed */
|
||||
} flags;
|
||||
|
||||
/*****************
|
||||
* Display state *
|
||||
*****************/
|
||||
long percentage;
|
||||
long double prev_elapsed_sec;
|
||||
long double prev_rate;
|
||||
long double prev_trans;
|
||||
struct pvdisplay_s {
|
||||
|
||||
/* Keep track of progress over last intervals to compute current average rate. */
|
||||
pvhistory_t *history; /* state at previous intervals (circular buffer) */
|
||||
int history_len; /* total size */
|
||||
int history_interval; /* seconds between each history entry */
|
||||
int history_first;
|
||||
int history_last;
|
||||
long double current_avg_rate; /* current average rate over last history intervals */
|
||||
|
||||
unsigned long long initial_offset;
|
||||
char *display_buffer;
|
||||
long display_buffer_size;
|
||||
int lastoutput_length; /* number of last-output bytes to show */
|
||||
unsigned char lastoutput_buffer[PV_SIZEOF_LASTOUTPUT_BUFFER];
|
||||
int prev_width; /* screen width last time we were called */
|
||||
int prev_length; /* length of last string we output */
|
||||
char str_name[PV_SIZEOF_STR_NAME];
|
||||
char str_transferred[PV_SIZEOF_STR_TRANSFERRED];
|
||||
char str_bufpercent[PV_SIZEOF_STR_BUFPERCENT];
|
||||
char str_timer[PV_SIZEOF_STR_TIMER];
|
||||
char str_rate[PV_SIZEOF_STR_RATE];
|
||||
char str_average_rate[PV_SIZEOF_STR_AVERAGE_RATE];
|
||||
char str_progress[PV_SIZEOF_STR_PROGRESS];
|
||||
char str_lastoutput[PV_SIZEOF_STR_LASTOUTPUT];
|
||||
char str_eta[PV_SIZEOF_STR_ETA];
|
||||
char str_fineta[PV_SIZEOF_STR_FINETA];
|
||||
unsigned long components_used; /* bitmask of components used */
|
||||
struct {
|
||||
const char *string;
|
||||
int length;
|
||||
} format[PV_FORMAT_ARRAY_MAX];
|
||||
bool display_visible; /* set once anything written to terminal */
|
||||
struct pvdisplay_segment_s { /* format string broken into segments */
|
||||
/* See pv__format_init() for more details. */
|
||||
/*@dependent@*/ /*@null@*/ const char *string_parameter; /* parameter after colon in %{x:} */
|
||||
pvdisplay_bytecount_t string_parameter_bytes; /* number of bytes in string_parameter */
|
||||
pvdisplay_component_t type; /* component type, -1 for static string */
|
||||
int8_t parameter; /* component parameter, such as bar style index */
|
||||
pvdisplay_width_t chosen_size; /* "n" from %<n>A, or 0 */
|
||||
pvdisplay_bytecount_t offset; /* start offset of this segment in the build buffer */
|
||||
pvdisplay_bytecount_t bytes; /* length of segment in bytes in the build buffer */
|
||||
pvdisplay_width_t width; /* displayed width of segment */
|
||||
} format[PV_FORMAT_ARRAY_MAX];
|
||||
|
||||
struct pvbarstyle_s barstyle[PV_BARSTYLE_MAX];
|
||||
|
||||
/* The last-written "n" bytes. */
|
||||
char lastwritten_buffer[PV_SIZEOF_LASTWRITTEN_BUFFER];
|
||||
|
||||
/* The most recently output complete line. */
|
||||
char previous_line[PV_SIZEOF_PREVLINE_BUFFER];
|
||||
/* The line being received now. */
|
||||
char next_line[PV_SIZEOF_PREVLINE_BUFFER];
|
||||
|
||||
/*@only@*/ /*@null@*/ char *display_buffer; /* buffer for display string */
|
||||
off_t initial_offset; /* offset when first opened (when watching fds) */
|
||||
size_t next_line_len; /* length of currently receiving line so far */
|
||||
|
||||
size_t format_segment_count; /* number of format string segments */
|
||||
|
||||
pvtransfercount_t count_type; /* type of count for transfer, rate, etc */
|
||||
|
||||
pvdisplay_width_t prev_screen_width; /* screen width last time pv_display() was called */
|
||||
|
||||
pvdisplay_bytecount_t display_buffer_size; /* size allocated to display buffer */
|
||||
pvdisplay_bytecount_t display_string_bytes; /* byte length of string in display buffer */
|
||||
pvdisplay_width_t display_string_width; /* displayed width of string in display buffer */
|
||||
pvdisplay_bytecount_t lastwritten_bytes; /* largest number of last-written bytes to show */
|
||||
|
||||
bool showing_timer; /* set if showing timer */
|
||||
bool showing_bytes; /* set if showing byte/line count */
|
||||
bool showing_ratio; /* set if showing monitoring in:out ratio */
|
||||
bool showing_rate; /* set if showing transfer rate */
|
||||
bool showing_last_written; /* set if displaying the last few bytes written */
|
||||
bool showing_previous_line; /* set if displaying the previously output line */
|
||||
|
||||
bool format_uses_colour; /* set if the format string uses colours */
|
||||
bool colour_permitted; /* whether colour is permitted for this display */
|
||||
bool sgr_code_active; /* set while SGR code is active in a display line */
|
||||
bool using_osc94; /* set if the format contains an OSC 9;4 code */
|
||||
bool final_update; /* set internally on the final update */
|
||||
bool output_produced; /* set once anything written to terminal */
|
||||
|
||||
} display;
|
||||
|
||||
/* Extra display for alternate outputs like a window title. */
|
||||
struct pvdisplay_s extra_display;
|
||||
|
||||
/************************************
|
||||
* Calculated state of the transfer *
|
||||
************************************/
|
||||
struct pvtransfercalc_s {
|
||||
long double transfer_rate; /* calculated transfer rate */
|
||||
long double average_rate; /* calculated average transfer rate */
|
||||
|
||||
long double prev_elapsed_sec; /* elapsed sec at which rate last calculated */
|
||||
long double prev_rate; /* last calculated instantaneous transfer rate */
|
||||
long double prev_trans; /* amount transferred since last rate calculation */
|
||||
long double current_avg_rate; /* current average rate over last history intervals */
|
||||
|
||||
long double rate_min; /* minimum measured transfer rate */
|
||||
long double rate_max; /* maximum measured transfer rate */
|
||||
long double rate_sum; /* sum of all measured transfer rates */
|
||||
long double ratesquared_sum; /* sum of the squares of each transfer rate */
|
||||
unsigned long measurements_taken; /* how many times the rate was measured */
|
||||
|
||||
/* Keep track of progress over last intervals to compute current average rate. */
|
||||
/*@null@*/ struct { /* state at previous intervals (circular buffer) */
|
||||
long double elapsed_sec; /* time since start of transfer */
|
||||
off_t transferred; /* amount transferred by that time */
|
||||
} *history;
|
||||
size_t history_len; /* total size of history array */
|
||||
size_t history_first; /* index of oldest entry */
|
||||
size_t history_last; /* index of newest entry */
|
||||
|
||||
off_t prev_transferred; /* total amount transferred when called last time */
|
||||
|
||||
double percentage; /* transfer percentage completion */
|
||||
} calc;
|
||||
|
||||
/********************
|
||||
* Cursor/IPC state *
|
||||
********************/
|
||||
struct pvcursorstate_s {
|
||||
/*@only@*/ /*@null@*/ char *lock_file; /* terminal lock filename */
|
||||
#ifdef HAVE_IPC
|
||||
int crs_shmid; /* ID of our shared memory segment */
|
||||
int crs_pvcount; /* number of `pv' processes in total */
|
||||
int crs_pvmax; /* highest number of `pv's seen */
|
||||
int *crs_y_top; /* pointer to Y coord of topmost `pv' */
|
||||
int crs_y_lastread; /* last value of _y_top seen */
|
||||
int crs_y_offset; /* our Y offset from this top position */
|
||||
int crs_needreinit; /* counter if we need to reinit cursor pos */
|
||||
bool crs_noipc; /* set if we can't use IPC */
|
||||
/*@keep@*/ /*@null@*/ struct pvipccursorstate_s *shared; /* data shared between instances */
|
||||
int shmid; /* ID of the shared memory segment */
|
||||
int pvcount; /* number of `pv' processes in total */
|
||||
int pvmax; /* highest number of `pv's seen */
|
||||
int y_lastread; /* last value of _y_top seen */
|
||||
int y_offset; /* our Y offset from this top position */
|
||||
int needreinit; /* counter for reinitialising cursor position */
|
||||
#endif /* HAVE_IPC */
|
||||
int crs_lock_fd; /* fd of lockfile, -1 if none open */
|
||||
char crs_lock_file[PV_SIZEOF_CRS_LOCK_FILE];
|
||||
int crs_y_start; /* our initial Y coordinate */
|
||||
int lock_fd; /* fd of lockfile, -1 if none open */
|
||||
int y_start; /* our initial Y coordinate */
|
||||
#ifdef HAVE_IPC
|
||||
bool noipc; /* set if IPC can't be used */
|
||||
#endif /* HAVE_IPC */
|
||||
bool disable; /* set if cursor positioning can't be used */
|
||||
} cursor;
|
||||
|
||||
/*******************
|
||||
* Transfer state *
|
||||
@@ -200,102 +419,275 @@ struct pvstate_s {
|
||||
* The transfer buffer is used for moving data from the input files
|
||||
* to the output when splice() is not available.
|
||||
*
|
||||
* If buffer_size is smaller than pv__target_bufsize, then
|
||||
* pv_transfer will try to reallocate transfer_buffer to make
|
||||
* buffer_size equal to pv__target_bufsize.
|
||||
* If buffer_size is smaller than control.target_buffer_size, then
|
||||
* pv_transfer() will try to reallocate transfer_buffer to make
|
||||
* buffer_size equal to control.target_buffer_size.
|
||||
*
|
||||
* Data from the input files is read into the buffer; read_position
|
||||
* is the offset in the buffer that we've read data up to.
|
||||
* is the offset in the buffer that data has been read up to.
|
||||
*
|
||||
* Data is written to the output from the buffer, and write_position
|
||||
* is the offset in the buffer that we've written data up to. It
|
||||
* is the offset in the buffer that data has been written up to. It
|
||||
* will always be less than or equal to read_position.
|
||||
*/
|
||||
unsigned char *transfer_buffer; /* data transfer buffer */
|
||||
unsigned long long buffer_size; /* size of buffer */
|
||||
unsigned long read_position; /* amount of data in buffer */
|
||||
unsigned long write_position; /* buffered data written */
|
||||
struct pvtransferstate_s {
|
||||
long double elapsed_seconds; /* how long the transfer has been running for */
|
||||
/*@only@*/ /*@null@*/ char *transfer_buffer; /* data transfer buffer */
|
||||
size_t buffer_size; /* size of buffer */
|
||||
size_t read_position; /* amount of data in buffer */
|
||||
size_t write_position; /* buffered data written */
|
||||
|
||||
/*
|
||||
* While reading from a file descriptor we keep track of how many
|
||||
* times in a row we've seen errors (read_errors_in_a_row), and
|
||||
* whether or not we have put a warning on stderr about read errors
|
||||
* on this fd (read_error_warning_shown).
|
||||
*
|
||||
* Whenever the active file descriptor changes from
|
||||
* last_read_skip_fd, we reset read_errors_in_a_row and
|
||||
* read_error_warning_shown to 0 for the new file descriptor and set
|
||||
* last_read_skip_fd to the new fd number.
|
||||
*
|
||||
* This way, we're treating each input file separately.
|
||||
*/
|
||||
int last_read_skip_fd;
|
||||
unsigned long read_errors_in_a_row;
|
||||
int read_error_warning_shown;
|
||||
ssize_t to_write; /* max to write this time around */
|
||||
ssize_t written; /* bytes sent to stdout this time */
|
||||
|
||||
size_t written_but_not_consumed; /* bytes in the output pipe, unread */
|
||||
|
||||
off_t total_bytes_read; /* total bytes read */
|
||||
off_t total_written; /* total bytes or lines written */
|
||||
off_t transferred; /* amount transferred (written - unconsumed) */
|
||||
|
||||
off_t otherside_transferred; /* amount transferred by the other side ("-M both") */
|
||||
|
||||
/* Keep track of line positions to backtrack written_but_not_consumed. */
|
||||
/*@only@*/ /*@null@*/ off_t *line_positions; /* line separator write positions (circular buffer) */
|
||||
size_t line_positions_capacity; /* total size of line position array */
|
||||
size_t line_positions_length; /* number of positions stored in array */
|
||||
size_t line_positions_head; /* index to use for next position */
|
||||
off_t last_output_position; /* write position last sent to output */
|
||||
|
||||
/*
|
||||
* While reading from a file descriptor, a count is kept of
|
||||
* how many times in a row there have been errors
|
||||
* (read_errors_in_a_row), and whether or not a warning has
|
||||
* been written to stderr about read errors on this fd
|
||||
* (read_error_warning_shown).
|
||||
*
|
||||
* Whenever the active file descriptor changes from
|
||||
* last_read_skip_fd, the read_errors_in_a_row is reset to 0
|
||||
* and read_error_warning_shown is set to false for the new
|
||||
* file descriptor, and last_read_skip_fd is set to the new
|
||||
* fd number.
|
||||
*
|
||||
* This allows each input file to be treated separately.
|
||||
*/
|
||||
off_t read_errors_in_a_row;
|
||||
int last_read_skip_fd;
|
||||
/* read_error_warning_shown is defined below. */
|
||||
#ifdef HAVE_SPLICE
|
||||
/*
|
||||
* These variables are used to keep track of whether splice() was
|
||||
* used; splice_failed_fd is the file descriptor that splice() last
|
||||
* failed on, so that we don't keep trying to use it on an fd that
|
||||
* doesn't support it, and splice_used is set to 1 if splice() was
|
||||
* used this time within pv_transfer().
|
||||
*/
|
||||
int splice_failed_fd;
|
||||
int splice_used;
|
||||
/*
|
||||
* File descriptors for an intermediate pipe, used when
|
||||
* neither input nor output are pipes; the size of the pipe
|
||||
* buffer; and how much input data is in the intermediate
|
||||
* pipe waiting to be passed to the output.
|
||||
*/
|
||||
int intermediate_pipe[2];
|
||||
int intermediate_pipe_buffer_size;
|
||||
int intermediate_pipe_buffer_used;
|
||||
/* File descriptor to /dev/null for splicing with -X. */
|
||||
int discard_fd;
|
||||
/*
|
||||
* splice_failed_fd is the input file descriptor that
|
||||
* splice() last failed on, to avoid continuing to try using
|
||||
* it on a file descriptor that doesn't support it.
|
||||
*/
|
||||
int splice_failed_fd;
|
||||
#endif
|
||||
long to_write; /* max to write this time around */
|
||||
long written; /* bytes sent to stdout this time */
|
||||
#ifdef HAVE_COPY_FILE_RANGE
|
||||
/*
|
||||
* copy_file_range_failed_fd is the input file descriptor
|
||||
* that copy_file_range() last failed on, to avoid
|
||||
* continuing to try using it on a file descriptor that
|
||||
* doesn't support it.
|
||||
*/
|
||||
int copy_file_range_failed_fd;
|
||||
#endif
|
||||
pvtransfermethod_t method; /* method used for most recent transfer */
|
||||
bool read_error_warning_shown;
|
||||
bool output_not_seekable; /* set if lseek() fails on output */
|
||||
} transfer;
|
||||
};
|
||||
|
||||
typedef struct pvprogramstatus_s *pvprogramstatus_t;
|
||||
typedef struct pvinputfiles_s *pvinputfiles_t;
|
||||
typedef struct pvcontrol_s *pvcontrol_t;
|
||||
typedef struct pvsignal_s *pvsignal_t;
|
||||
typedef struct pvtransientflags_s *pvtransientflags_t;
|
||||
typedef struct pvdisplay_s *pvdisplay_t;
|
||||
typedef struct pvdisplay_segment_s *pvdisplay_segment_t;
|
||||
typedef struct pvtransfercalc_s *pvtransfercalc_t;
|
||||
typedef struct pvcursorstate_s *pvcursorstate_t;
|
||||
typedef struct pvtransferstate_s *pvtransferstate_t;
|
||||
|
||||
/*
|
||||
* Structure defining the current state of a single watched file descriptor.
|
||||
* The full definition needs to go here as it refers to sub-structures of
|
||||
* the main state, defined above.
|
||||
*/
|
||||
struct pvwatchfd_s {
|
||||
unsigned int watch_pid; /* PID to watch */
|
||||
int watch_fd; /* fd to watch, -1 = not displayed */
|
||||
struct pvtransientflags_s flags; /* transient flags */
|
||||
struct pvtransferstate_s transfer; /* transfer state */
|
||||
struct pvtransfercalc_s calc; /* calculated transfer state */
|
||||
struct pvdisplay_s display; /* display data */
|
||||
#ifdef __APPLE__
|
||||
#else
|
||||
char file_fdinfo[PV_SIZEOF_FILE_FDINFO]; /* path to /proc fdinfo file */
|
||||
char file_fd[PV_SIZEOF_FILE_FD]; /* path to /proc fd symlink */
|
||||
nullable_string_ptr file_fdinfo; /* path to /proc fdinfo file */
|
||||
nullable_string_ptr file_fdsymlink; /* path to /proc fd symlink */
|
||||
#endif
|
||||
char file_fdpath[PV_SIZEOF_FILE_FDPATH]; /* path to file that was opened */
|
||||
char display_name[PV_SIZEOF_DISPLAY_NAME]; /* name to show on progress bar */
|
||||
nullable_string_ptr file_fdpath; /* path to file that was opened */
|
||||
/*@keep@ */ char display_name[PV_SIZEOF_DISPLAY_NAME]; /* name to show on progress bar */
|
||||
struct stat sb_fd; /* stat of fd symlink */
|
||||
struct stat sb_fd_link; /* lstat of fd symlink */
|
||||
unsigned long long size; /* size of whole file, 0 if unknown */
|
||||
long long position; /* position last seen at */
|
||||
struct timeval start_time; /* time we started watching the fd */
|
||||
off_t size; /* size of whole file, 0 if unknown */
|
||||
off_t position; /* position last seen at */
|
||||
struct timespec start_time; /* time the watch of this fd began */
|
||||
struct timespec end_time; /* time the fd was marked as closed */
|
||||
struct timespec total_stoppage_time; /* total time spent stopped */
|
||||
pid_t watch_pid; /* PID the fd belongs to */
|
||||
int watch_fd; /* fd to watch */
|
||||
bool closed; /* true once the fd is closed */
|
||||
bool displayable; /* false if not displayable */
|
||||
bool unused; /* true if free for re-use */
|
||||
};
|
||||
typedef struct pvwatchfd_s *pvwatchfd_t;
|
||||
|
||||
void pv_error(pvstate_t, char *, ...);
|
||||
/*
|
||||
* Read-only counterparts to the above structure pointers, to be used in
|
||||
* function declarations where the function definitely shouldn't be altering
|
||||
* the contents of the structure.
|
||||
*/
|
||||
typedef const struct pvprogramstatus_s * readonly_pvprogramstatus_t;
|
||||
typedef const struct pvinputfiles_s * readonly_pvinputfiles_t;
|
||||
typedef const struct pvcontrol_s * readonly_pvcontrol_t;
|
||||
typedef const struct pvsignal_s * readonly_pvsignal_t;
|
||||
typedef const struct pvtransientflags_s * readonly_pvtransientflags_t;
|
||||
typedef const struct pvdisplay_s * readonly_pvdisplay_t;
|
||||
typedef const struct pvdisplay_segment_s * readonly_pvdisplay_segment_t;
|
||||
typedef const struct pvtransfercalc_s * readonly_pvtransfercalc_t;
|
||||
typedef const struct pvcursorstate_s * readonly_pvcursorstate_t;
|
||||
typedef const struct pvtransferstate_s * readonly_pvtransferstate_t;
|
||||
|
||||
/*
|
||||
* Structure containing the parameters used by formatters.
|
||||
*/
|
||||
struct pvformatter_args_s {
|
||||
/*@dependent@*/ pvdisplay_t display; /* the display being updated */
|
||||
/*@dependent@*/ pvdisplay_segment_t segment; /* the segment of the display */
|
||||
/*@dependent@*/ readonly_pvprogramstatus_t status; /* program status */
|
||||
/*@dependent@*/ readonly_pvcontrol_t control; /* control settings */
|
||||
/*@dependent@*/ readonly_pvtransferstate_t transfer; /* transfer state */
|
||||
/*@dependent@*/ readonly_pvtransfercalc_t calc; /* calculated transfer state */
|
||||
/*@dependent@*/ char *buffer; /* buffer to write formatted segments into */
|
||||
pvdisplay_bytecount_t buffer_size; /* size of the buffer */
|
||||
pvdisplay_bytecount_t offset; /* current write position in the buffer */
|
||||
};
|
||||
typedef struct pvformatter_args_s *pvformatter_args_t;
|
||||
|
||||
|
||||
/* Pointer to a formatter function. */
|
||||
typedef pvdisplay_bytecount_t (*pvdisplay_formatter_t)(pvformatter_args_t);
|
||||
|
||||
|
||||
/*
|
||||
* Structure defining a format string sequence following a %.
|
||||
*/
|
||||
struct pvdisplay_component_s {
|
||||
/*@null@ */ const char *match; /* string to match */
|
||||
/*@null@ */ pvdisplay_formatter_t function; /* function to call */
|
||||
bool dynamic; /* whether it can scale with screen size */
|
||||
};
|
||||
|
||||
int pv_main_loop(pvstate_t);
|
||||
void pv_display(pvstate_t, long double, long long, long long);
|
||||
long pv_transfer(pvstate_t, int, int *, int *, unsigned long long, long *);
|
||||
void pv_set_buffer_size(unsigned long long, int);
|
||||
int pv_next_file(pvstate_t, int, int);
|
||||
void pv_calculate_transfer_rate(pvtransfercalc_t, readonly_pvtransferstate_t, readonly_pvcontrol_t, readonly_pvdisplay_t, bool);
|
||||
|
||||
long pv_seconds_remaining(const off_t, const off_t, const long double);
|
||||
void pv_si_prefix(long double *, char *, const long double, pvtransfercount_t);
|
||||
void pv_describe_amount(char *, size_t, const char *, long double, char *, char *, pvtransfercount_t);
|
||||
|
||||
int8_t pv_display_barstyle_index(pvformatter_args_t, const char *);
|
||||
|
||||
pvdisplay_bytecount_t pv_formatter_segmentcontent(char *, pvformatter_args_t);
|
||||
|
||||
/*
|
||||
* Formatting functions.
|
||||
*
|
||||
* Each formatting function takes a state, the current display, and the
|
||||
* segment it's for; it also takes a buffer, with a particular size, and an
|
||||
* offset at which to start writing to the buffer.
|
||||
*
|
||||
* If the component is dynamically sized (such as a progress bar with no
|
||||
* chosen_size constraint), the segment's "width" is expected to have
|
||||
* already been populated by the caller, with the target width.
|
||||
*
|
||||
* The function writes the appropriate string to the buffer at the offset,
|
||||
* and updates the segment's "offset" and "bytes". The number of bytes
|
||||
* written ("bytes") is also returned; it will be 0 if the string would not
|
||||
* fit into the buffer.
|
||||
*
|
||||
* The caller is expected to update the segment's "width".
|
||||
*
|
||||
* If called with a buffer size of 0, only the side effects occur (such as
|
||||
* setting flags like display->showing_timer).
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_progress(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_progress_bar_only(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_progress_amount_only(pvformatter_args_t);
|
||||
size_t pv_osc94_format(char *, size_t, readonly_pvcontrol_t, readonly_pvtransfercalc_t);
|
||||
pvdisplay_bytecount_t pv_formatter_progress_conemu(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_bar_default(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_bar_plain(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_bar_block(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_bar_granular(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_bar_shaded(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_timer(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_eta(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_fineta(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_rate(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_average_rate(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_bytes(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_ratio(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_buffer_percent(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_last_written(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_previous_line(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_name(pvformatter_args_t);
|
||||
pvdisplay_bytecount_t pv_formatter_sgr(pvformatter_args_t);
|
||||
|
||||
void pv_display (pvprogramstatus_t, readonly_pvcontrol_t, pvtransientflags_t,
|
||||
readonly_pvtransferstate_t, pvtransfercalc_t,
|
||||
pvcursorstate_t, pvdisplay_t, /*@null@ */ pvdisplay_t, bool);
|
||||
|
||||
ssize_t pv_transfer(pvstate_t, int, bool *, bool *, off_t, long *);
|
||||
int pv_next_file(pvstate_t, unsigned int, int);
|
||||
/*@keep@*/ const char *pv_current_file_name(pvstate_t);
|
||||
|
||||
unsigned int pv_update_calc_average_rate_window(pvtransfercalc_t, unsigned int);
|
||||
void pv_reset_calc(pvtransfercalc_t);
|
||||
void pv_reset_transfer(pvtransferstate_t);
|
||||
void pv_reset_flags(pvtransientflags_t);
|
||||
void pv_reset_display(pvdisplay_t);
|
||||
void pv_freecontents_display(pvdisplay_t);
|
||||
void pv_freecontents_transfer(pvtransferstate_t);
|
||||
void pv_freecontents_calc(pvtransfercalc_t);
|
||||
void pv_freecontents_watchfd(pvwatchfd_t);
|
||||
void pv_freecontents_watchfd_items(struct pvwatcheditem_s *, unsigned int);
|
||||
|
||||
void pv_write_retry(int, const char *, size_t);
|
||||
void pv_tty_write(readonly_pvtransientflags_t, const char *, size_t);
|
||||
|
||||
void pv_crs_fini(pvstate_t);
|
||||
void pv_crs_init(pvstate_t);
|
||||
void pv_crs_update(pvstate_t, const char *);
|
||||
void pv_crs_fini(pvcursorstate_t, readonly_pvcontrol_t, pvtransientflags_t);
|
||||
void pv_crs_init(pvcursorstate_t, readonly_pvcontrol_t, pvtransientflags_t);
|
||||
void pv_crs_update(pvcursorstate_t, readonly_pvcontrol_t, pvtransientflags_t, const char *);
|
||||
#ifdef HAVE_IPC
|
||||
void pv_crs_needreinit(pvstate_t);
|
||||
void pv_crs_needreinit(pvcursorstate_t);
|
||||
#endif
|
||||
|
||||
void pv_sig_allowpause(void);
|
||||
void pv_sig_checkbg(void);
|
||||
void pv_sig_nopause(void);
|
||||
|
||||
void pv_remote_init(pvstate_t);
|
||||
void pv_remote_check(pvstate_t);
|
||||
void pv_remote_fini(pvstate_t);
|
||||
int pv_remote_set(pvstate_t);
|
||||
bool pv_remote_check(pvstate_t);
|
||||
|
||||
int pv_watchfd_info(pvstate_t, pvwatchfd_t, int);
|
||||
int pv_watchfd_changed(pvwatchfd_t);
|
||||
long long pv_watchfd_position(pvwatchfd_t);
|
||||
int pv_watchpid_scanfds(pvstate_t, pvstate_t, unsigned int, int *, pvwatchfd_t *, pvstate_t *, int *);
|
||||
bool pv_watchfd_changed(pvwatchfd_t);
|
||||
off_t pv_watchfd_position(pvwatchfd_t);
|
||||
int pv_watchpid_scanfds(pvstate_t, pid_t, int, int *, pvwatchfd_t *);
|
||||
void pv_watchpid_setname(pvstate_t, pvwatchfd_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -303,5 +695,3 @@ void pv_watchpid_setname(pvstate_t, pvwatchfd_t);
|
||||
#endif
|
||||
|
||||
#endif /* _PV_INTERNAL_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+256
-49
@@ -1,20 +1,42 @@
|
||||
/*
|
||||
* Functions used across the program. Include "config.h" first.
|
||||
* Functions used across the program.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#ifndef _PV_H
|
||||
#define _PV_H 1
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Exit status bitmask values.
|
||||
*/
|
||||
#define PV_ERROREXIT_REMOTE_OR_PID 1
|
||||
#define PV_ERROREXIT_SAF 1 /* store and forward error */
|
||||
#define PV_ERROREXIT_MONITOR 1 /* monitor mode error */
|
||||
#define PV_ERROREXIT_ACCESS 2
|
||||
#define PV_ERROREXIT_OUROBOROS 4
|
||||
#define PV_ERROREXIT_TRANSITION 8
|
||||
#define PV_ERROREXIT_TRANSFER 16
|
||||
#define PV_ERROREXIT_SIGNAL 32
|
||||
#define PV_ERROREXIT_MEMORY 64
|
||||
|
||||
/*
|
||||
* Opaque structure for PV internal state.
|
||||
*/
|
||||
@@ -25,9 +47,10 @@ typedef struct pvstate_s *pvstate_t;
|
||||
* Valid number types for pv_getnum_check().
|
||||
*/
|
||||
typedef enum {
|
||||
PV_NUMTYPE_INTEGER,
|
||||
PV_NUMTYPE_DOUBLE
|
||||
} pv_numtype_t;
|
||||
PV_NUMTYPE_ANY_WITH_SUFFIX,
|
||||
PV_NUMTYPE_BARE_INTEGER,
|
||||
PV_NUMTYPE_BARE_DOUBLE
|
||||
} pv_numtype;
|
||||
|
||||
|
||||
/*
|
||||
@@ -35,128 +58,305 @@ typedef enum {
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return the given string converted to a double.
|
||||
* Return true if the character is an ASCII digit.
|
||||
*/
|
||||
extern double pv_getnum_d(const char *);
|
||||
extern bool pv_isdigit(char);
|
||||
|
||||
/*
|
||||
* Return the given string converted to an unsigned integer.
|
||||
* Return the numeric value of a string representing a positive decimal time
|
||||
* interval.
|
||||
*/
|
||||
extern unsigned int pv_getnum_ui(const char *);
|
||||
extern double pv_getnum_interval(const char *);
|
||||
|
||||
/*
|
||||
* Return the given string converted to an unsigned long long.
|
||||
* Return the numeric value of a string representing a size, interpreting
|
||||
* suffixes in decimal units (multiples of 1000) instead of multiples of
|
||||
* 1024 if the second argument is true.
|
||||
*
|
||||
* Optionally also places the result in a long double.
|
||||
*/
|
||||
extern unsigned long long pv_getnum_ull(const char *);
|
||||
extern off_t pv_getnum_size(const char *, bool, /*@null@ */ long double *);
|
||||
|
||||
/*
|
||||
* Return zero if the given string is a number of the given type. NB an
|
||||
* integer is both a valid integer and a valid double.
|
||||
* Return the numeric value of a string representing a count such as screen
|
||||
* width, interpreting it the same way as pv_getnum_size().
|
||||
*/
|
||||
extern int pv_getnum_check(const char *, pv_numtype_t);
|
||||
extern unsigned int pv_getnum_count(const char *, bool);
|
||||
|
||||
/*
|
||||
* Return true if the given string is a number of the given type. Note that
|
||||
* an integer is both a valid integer and a valid double.
|
||||
*/
|
||||
extern bool pv_getnum_check(const char *, pv_numtype);
|
||||
|
||||
/*
|
||||
* Return a value representing the first amount as a percentage of the
|
||||
* second total, i.e. 100*amount/total. If the second value, the total, is
|
||||
* zero or less, return 0.
|
||||
*/
|
||||
extern double pv_percentage(off_t, const off_t);
|
||||
|
||||
/*
|
||||
* String handling wrappers.
|
||||
*/
|
||||
|
||||
/* String pointer that can be null. */
|
||||
typedef /*@null@*/ char * nullable_string_ptr;
|
||||
|
||||
/*
|
||||
* Wrapper for sprintf(), falling back to sprintf() on systems without that
|
||||
* Wrapper for snprintf(), falling back to sprintf() on systems without that
|
||||
* function.
|
||||
*/
|
||||
extern int pv_snprintf(char *, size_t, const char *, ...);
|
||||
|
||||
/*
|
||||
* Wrapper for asprintf(), providing an equivalent on systems without that
|
||||
* function.
|
||||
*/
|
||||
extern int pv_asprintf(nullable_string_ptr *, const char *, ...);
|
||||
|
||||
/*
|
||||
* Implementation of strlcat() where it is unavailable: append a string to a
|
||||
* buffer, constraining the buffer to a particular size and ensuring
|
||||
* termination with '\0'.
|
||||
*/
|
||||
extern size_t pv_strlcat(char *, const char *, size_t);
|
||||
|
||||
/*
|
||||
* Allocate and return a duplicate of a \0-terminated string, ensuring that
|
||||
* the duplicate is also \0-terminated. Returns NULL on error.
|
||||
*/
|
||||
/*@null@ */ /*@only@ */ extern char *pv_strdup(const /*@null@ */ char *);
|
||||
|
||||
/*
|
||||
* Return a pointer to the last matching character in the buffer, or NULL if
|
||||
* not found.
|
||||
*/
|
||||
/*@null@ */ /*@temp@ */ extern void *pv_memrchr(const void *, int, size_t);
|
||||
|
||||
/*
|
||||
* Return the displayed width of a string.
|
||||
*/
|
||||
extern size_t pv_strwidth(const char *, size_t);
|
||||
|
||||
/*
|
||||
* Return true if the character is printable 7-bit ASCII.
|
||||
*/
|
||||
extern bool pv_isprint(char);
|
||||
|
||||
/*
|
||||
* Functions relating to elapsed time.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Read the current elapsed time, relative to an unspecified point in the
|
||||
* past, and store it in the given timespec buffer. The time is guaranteed
|
||||
* to not go backwards and does not count time when the system was
|
||||
* suspended. See clock_gettime(2) with CLOCK_MONOTONIC.
|
||||
*/
|
||||
void pv_elapsedtime_read(struct timespec *);
|
||||
|
||||
/* Set the time in the timespec to zero. */
|
||||
void pv_elapsedtime_zero(struct timespec *);
|
||||
|
||||
/* Copy the second timespec into the first. Analogous to strcpy(3). */
|
||||
void pv_elapsedtime_copy(struct timespec *, const struct timespec *);
|
||||
|
||||
/*
|
||||
* Return -1, 0, or 1 depending on whether the first time is earlier than,
|
||||
* equal to, or later than the second time. Analogous to strcmp(3).
|
||||
*/
|
||||
int pv_elapsedtime_compare(const struct timespec *, const struct timespec *);
|
||||
|
||||
/* Add the latter two timespecs and store them in the first timespec. */
|
||||
void pv_elapsedtime_add(struct timespec *, const struct timespec *, const struct timespec *);
|
||||
|
||||
/* Add a number of nanoseconds to a timespec. */
|
||||
void pv_elapsedtime_add_nsec(struct timespec *, long long);
|
||||
|
||||
/* Set the first timespec to the second minus the third. */
|
||||
void pv_elapsedtime_subtract(struct timespec *, const struct timespec *, const struct timespec *);
|
||||
|
||||
/* Convert a timespec to seconds. */
|
||||
long double pv_elapsedtime_seconds(const struct timespec *);
|
||||
|
||||
/* Sleep for a number of nanoseconds. */
|
||||
void pv_nanosleep(long long);
|
||||
|
||||
|
||||
/*
|
||||
* Main PV functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create a new state structure, and return it, or 0 (NULL) on error.
|
||||
* Set the error message prefix. If the new prefix is NULL, the current
|
||||
* prefix is cleared.
|
||||
*/
|
||||
extern pvstate_t pv_state_alloc(const char *);
|
||||
extern void pv_set_error_prefix(/*@null@ */ const char *);
|
||||
|
||||
/*
|
||||
* Set the formatting string, given a set of old-style formatting options.
|
||||
* Output an error message. If anything has been sent to the terminal
|
||||
* already, then put a newline before the message, to avoid writing over
|
||||
* what was sent earlier.
|
||||
*/
|
||||
extern void pv_state_set_format(pvstate_t state, bool progress,
|
||||
bool timer, bool eta,
|
||||
bool fineta, bool rate,
|
||||
bool average_rate, bool bytes,
|
||||
bool bufpercent,
|
||||
unsigned int lastwritten,
|
||||
const char *name);
|
||||
extern void pv_error(char *, ...);
|
||||
|
||||
/*
|
||||
* Output an error message, like pv_error(), but following the message with
|
||||
* a colon, a space, and the result of strerror(errno).
|
||||
*/
|
||||
extern void pv_perror(char *, ...);
|
||||
|
||||
/*
|
||||
* Check that a file descriptor is open on /dev/null, returning true if so.
|
||||
* Otherwise return false; if the second argument is true, reports the
|
||||
* problem with pv_error() before returning.
|
||||
*/
|
||||
extern bool pv_fd_is_dev_null(int, bool);
|
||||
|
||||
|
||||
/*
|
||||
* Create a new state structure, and return it, or 0 (NULL) on error.
|
||||
*/
|
||||
extern /*@null@*/ /*@only@*/ pvstate_t pv_state_alloc(void);
|
||||
|
||||
/*
|
||||
* Clear the calculated parts of a state structure.
|
||||
*/
|
||||
extern void pv_state_reset(pvstate_t state);
|
||||
|
||||
/*
|
||||
* Set the format options and use them to build a default formatting string.
|
||||
* The default string is used if no format string is explicitly set.
|
||||
*/
|
||||
typedef struct {
|
||||
size_t lastwritten; /* --last-written (amount) */
|
||||
bool progress; /* --progress */
|
||||
bool timer; /* --timer */
|
||||
bool eta; /* --eta */
|
||||
bool fineta; /* --fineta */
|
||||
bool rate; /* --rate */
|
||||
bool average_rate; /* --average-rate */
|
||||
bool bytes; /* --bytes */
|
||||
bool bufpercent; /* --buffer-percent */
|
||||
} pvformatoptions_s;
|
||||
extern void pv_state_set_format_options(pvstate_t, pvformatoptions_s);
|
||||
|
||||
/* Append a string to the default format, and trigger a format reparse. */
|
||||
void pv_state_append_to_default_format(pvstate_t, /*@null@ */ const char *);
|
||||
|
||||
/*
|
||||
* Set the various options.
|
||||
*/
|
||||
extern void pv_state_force_set(pvstate_t, bool);
|
||||
extern void pv_state_cursor_set(pvstate_t, bool);
|
||||
extern void pv_state_use_osc94_set(pvstate_t, bool);
|
||||
extern void pv_state_show_stats_set(pvstate_t, bool);
|
||||
extern void pv_state_numeric_set(pvstate_t, bool);
|
||||
extern void pv_state_wait_set(pvstate_t, bool);
|
||||
extern void pv_state_delay_start_set(pvstate_t, double);
|
||||
extern void pv_state_rate_gauge_set(pvstate_t, bool);
|
||||
extern void pv_state_linemode_set(pvstate_t, bool);
|
||||
extern void pv_state_bits_set(pvstate_t, bool);
|
||||
extern void pv_state_null_set(pvstate_t, bool);
|
||||
extern void pv_state_no_op_set(pvstate_t, bool);
|
||||
extern void pv_state_decimal_units_set(pvstate_t, bool);
|
||||
extern void pv_state_null_terminated_lines_set(pvstate_t, bool);
|
||||
extern void pv_state_no_display_set(pvstate_t, bool);
|
||||
extern void pv_state_skip_errors_set(pvstate_t, unsigned int);
|
||||
extern void pv_state_error_skip_block_set(pvstate_t, off_t);
|
||||
extern void pv_state_stop_at_size_set(pvstate_t, bool);
|
||||
extern void pv_state_sync_after_write_set(pvstate_t, bool);
|
||||
extern void pv_state_direct_io_set(pvstate_t, bool);
|
||||
extern void pv_state_rate_limit_set(pvstate_t, unsigned long long);
|
||||
extern void pv_state_target_buffer_size_set(pvstate_t, unsigned long long);
|
||||
extern void pv_state_sparse_output_set(pvstate_t, bool);
|
||||
extern void pv_state_rate_limit_set(pvstate_t, long double, bool, bool);
|
||||
extern void pv_state_target_buffer_size_set(pvstate_t, size_t);
|
||||
extern void pv_state_no_splice_set(pvstate_t, bool);
|
||||
extern void pv_state_size_set(pvstate_t, unsigned long long);
|
||||
extern void pv_state_pipe_buffer_size_set(pvstate_t, size_t);
|
||||
extern void pv_state_discard_input_set(pvstate_t, bool);
|
||||
extern void pv_state_size_set(pvstate_t, off_t);
|
||||
extern void pv_state_interval_set(pvstate_t, double);
|
||||
extern void pv_state_width_set(pvstate_t, unsigned int);
|
||||
extern void pv_state_height_set(pvstate_t, unsigned int);
|
||||
extern void pv_state_name_set(pvstate_t, const char *);
|
||||
extern void pv_state_format_string_set(pvstate_t, const char *);
|
||||
extern void pv_state_watch_pid_set(pvstate_t, unsigned int);
|
||||
extern void pv_state_watch_fd_set(pvstate_t, int);
|
||||
extern void pv_state_average_rate_window_set(pvstate_t, int);
|
||||
extern void pv_state_width_set(pvstate_t, unsigned int, bool);
|
||||
extern void pv_state_height_set(pvstate_t, unsigned int, bool);
|
||||
extern void pv_state_name_set(pvstate_t, /*@null@*/ const char *);
|
||||
extern void pv_state_default_bar_style_set(pvstate_t, /*@null@ */ const char *);
|
||||
extern void pv_state_format_string_set(pvstate_t, /*@null@*/ const char *);
|
||||
extern void pv_state_extra_display_set(pvstate_t, /*@null@*/ const char *);
|
||||
extern void pv_state_output_set(pvstate_t, int, const char *);
|
||||
extern void pv_state_average_rate_window_set(pvstate_t, unsigned int);
|
||||
extern void pv_state_set_terminal_supports_utf8(pvstate_t, bool);
|
||||
extern void pv_state_othermonitor_set(pvstate_t, pid_t, int, int);
|
||||
extern void pv_state_cancel_output_if_empty_format_string(pvstate_t);
|
||||
|
||||
extern void pv_state_inputfiles(pvstate_t, int, const char **);
|
||||
extern void pv_state_inputfiles(pvstate_t, unsigned int, const char **);
|
||||
extern void pv_state_watchfds(pvstate_t, unsigned int, const pid_t *, const int *);
|
||||
|
||||
/*
|
||||
* Work out whether we are in the foreground.
|
||||
* Return true if either this is the foreground process on the terminal, or
|
||||
* if the output is not a terminal; false otherwise.
|
||||
*/
|
||||
extern bool pv_in_foreground(void);
|
||||
|
||||
/*
|
||||
* Work out the terminal size.
|
||||
* Populate *width and *height with the current terminal size.
|
||||
*/
|
||||
extern void pv_screensize(unsigned int *width, unsigned int *height);
|
||||
|
||||
/*
|
||||
* Calculate the total size of all input files.
|
||||
*/
|
||||
extern unsigned long long pv_calc_total_size(pvstate_t);
|
||||
extern off_t pv_calc_total_size(pvstate_t);
|
||||
|
||||
/*
|
||||
* Set up signal handlers ready for running the main loop.
|
||||
*/
|
||||
extern void pv_sig_init(pvstate_t);
|
||||
|
||||
#ifdef PV_REMOTE_CONTROL
|
||||
/*
|
||||
* Return true if SIGUSR2 has been received, and indicate the sender.
|
||||
*/
|
||||
extern bool pv_sigusr2_received(pvstate_t, pid_t *);
|
||||
|
||||
/*
|
||||
* Return true if SIGUSR1 has been received, and indicate the sender.
|
||||
*/
|
||||
extern bool pv_sigusr1_received(pvstate_t, pid_t *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return a stream pointer for a control file associated with a particular
|
||||
* process ID and signal.
|
||||
*/
|
||||
/*@null@ */
|
||||
/*@dependent@ */
|
||||
extern FILE *pv_open_controlfile(char *, size_t, pid_t, int, bool);
|
||||
|
||||
/*
|
||||
* Enter the main transfer loop, transferring all input files to the output.
|
||||
*/
|
||||
extern int pv_main_loop(pvstate_t);
|
||||
|
||||
/*
|
||||
* Watch the selected file descriptor of the selected process.
|
||||
* Watch the selected file descriptors of the selected processes.
|
||||
*/
|
||||
extern int pv_watchfd_loop(pvstate_t);
|
||||
|
||||
/*
|
||||
* Watch the selected process.
|
||||
* Watch the progress of another pv process.
|
||||
*/
|
||||
extern int pv_watchpid_loop(pvstate_t);
|
||||
extern int pv_query_loop(pvstate_t, pid_t);
|
||||
|
||||
/*
|
||||
* Set the options of another pv process.
|
||||
*/
|
||||
int pv_remote_set(pvstate_t, pid_t);
|
||||
|
||||
/*
|
||||
* Query another pv process for its elapsed transfer time, amount
|
||||
* transferred, and total size, and update the local state with those
|
||||
* values. Optionally also return the total size separately. Reports
|
||||
* errors unless "silent" is true.
|
||||
*/
|
||||
int pv_remote_transferstate_fetch(pvstate_t state, pid_t query, /*@null@ */ off_t *sizeptr, bool silent);
|
||||
|
||||
/*
|
||||
* Shut down signal handlers after running the main loop.
|
||||
@@ -166,8 +366,17 @@ extern void pv_sig_fini(pvstate_t);
|
||||
/*
|
||||
* Free a state structure, after which it can no longer be used.
|
||||
*/
|
||||
extern void pv_state_free(pvstate_t);
|
||||
extern void pv_state_free(/*@only@*/ pvstate_t);
|
||||
|
||||
/*
|
||||
* Return a string listing all supported format sequences.
|
||||
*/
|
||||
/*@null@*/ char *pv_format_sequences(void);
|
||||
|
||||
#if ! HAVE_SETPROCTITLE
|
||||
void initproctitle(int, char **);
|
||||
void setproctitle(const char *, ...);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
# if __STDC_VERSION__ < 199901L && !defined(__func__)
|
||||
@@ -179,7 +388,7 @@ extern void pv_state_free(pvstate_t);
|
||||
# endif
|
||||
# define debug(x,...) debugging_output(__func__, __FILE__, __LINE__, x, __VA_ARGS__)
|
||||
#else
|
||||
# define debug(x,...) do { } while (0)
|
||||
# define debug(x,...) /*@-noeffect@*/ do { } while (0) /*@+noeffect@*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -198,5 +407,3 @@ void debugging_output(const char *, const char *, int, const char *, ...);
|
||||
#endif
|
||||
|
||||
#endif /* _PV_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Small reimplementation of getopt().
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef HAVE_GETOPT
|
||||
|
||||
char *minioptarg = NULL;
|
||||
int minioptind = 0;
|
||||
int miniopterr = 1;
|
||||
int minioptopt = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Minimalist getopt() clone, which handles short options only and doesn't
|
||||
* permute argv[].
|
||||
*/
|
||||
int minigetopt(int argc, char **argv, char *optstring)
|
||||
{
|
||||
static int nextchar = 0;
|
||||
int optchar;
|
||||
int i;
|
||||
|
||||
if ((0 == minioptind) && (argc > 0))
|
||||
minioptind++;
|
||||
|
||||
if ((nextchar > 0) && (0 == argv[minioptind][nextchar])) {
|
||||
minioptind++;
|
||||
nextchar = 0;
|
||||
}
|
||||
|
||||
if (minioptind >= argc)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* End of options if arg doesn't start with "-"
|
||||
*/
|
||||
if (argv[minioptind][0] != '-')
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* End of options if arg is just "-"
|
||||
*/
|
||||
if (0 == argv[minioptind][1])
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* End of options if arg is "--", but don't include the "--" in the
|
||||
* non-option arguments
|
||||
*/
|
||||
if (('-' == argv[minioptind][1]) && (0 == argv[minioptind][2])) {
|
||||
minioptind++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == nextchar)
|
||||
nextchar = 1;
|
||||
|
||||
optchar = argv[minioptind][nextchar++];
|
||||
|
||||
for (i = 0; optstring[i] != 0 && optstring[i] != optchar; i++) {
|
||||
}
|
||||
|
||||
if (0 == optstring[i]) {
|
||||
minioptopt = optchar;
|
||||
if (miniopterr)
|
||||
fprintf(stderr, "%s: invalid option -- %c\n", argv[0], optchar);
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (optstring[i + 1] != ':') {
|
||||
minioptarg = NULL;
|
||||
return optchar;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point we've got an option that takes an argument.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Next character isn't 0, so the argument is within this array
|
||||
* element (i.e. "-dFOO").
|
||||
*/
|
||||
if (argv[minioptind][nextchar] != 0) {
|
||||
minioptarg = &(argv[minioptind][nextchar]);
|
||||
nextchar = 0;
|
||||
minioptind++;
|
||||
return optchar;
|
||||
}
|
||||
|
||||
/*
|
||||
* Argument is in the next array element (i.e. "-d FOO").
|
||||
*/
|
||||
nextchar = 0;
|
||||
minioptind++;
|
||||
if (minioptind >= argc) {
|
||||
fprintf(stderr, "%s: option `-%c' requires an argument\n", argv[0], optchar);
|
||||
return ':';
|
||||
}
|
||||
minioptarg = argv[minioptind++];
|
||||
|
||||
return optchar;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GETOPT */
|
||||
|
||||
/* EOF */
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Very minimal (and stupid) implementation of gettext, with a fixed lookup
|
||||
* table.
|
||||
*
|
||||
* This library ONLY handles gettext(), and that only for the basic form (it
|
||||
* translates strings to other strings with no other modification, so %2$d
|
||||
* style constructs are not dealt with). The setlocale(), bindtextdomain(),
|
||||
* and textdomain() functions are ignored.
|
||||
*
|
||||
* To use this library, create a function that, given a language string,
|
||||
* returns a struct msg_table_s[] of msgid and msgstr pairs, with the end
|
||||
* of the table being marked by a NULL msgid. The po2table.sh script will do
|
||||
* this.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
|
||||
struct msgtable_s {
|
||||
char *msgid;
|
||||
char *msgstr;
|
||||
};
|
||||
|
||||
#if ENABLE_NLS
|
||||
struct msgtable_s *minigettext__gettable(char *);
|
||||
#else /* ENABLE_NLS */
|
||||
struct msgtable_s *minigettext__gettable(char *a)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
char *minisetlocale(const char *a, const char *b)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *minibindtextdomain(const char *a, const char *b)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *minitextdomain(const char *a)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *minigettext(const char *msgid)
|
||||
{
|
||||
static struct msgtable_s *table = NULL;
|
||||
static int tried_lang = 0;
|
||||
char *lang;
|
||||
int i;
|
||||
|
||||
if (NULL == msgid)
|
||||
return NULL;
|
||||
|
||||
if (0 == tried_lang) {
|
||||
lang = getenv("LANGUAGE");
|
||||
if (lang)
|
||||
table = minigettext__gettable(lang);
|
||||
|
||||
if (NULL == table) {
|
||||
lang = getenv("LANG");
|
||||
if (lang)
|
||||
table = minigettext__gettable(lang);
|
||||
}
|
||||
|
||||
if (NULL == table) {
|
||||
lang = getenv("LC_ALL");
|
||||
if (lang)
|
||||
table = minigettext__gettable(lang);
|
||||
}
|
||||
|
||||
if (NULL == table) {
|
||||
lang = getenv("LC_MESSAGES");
|
||||
if (lang)
|
||||
table = minigettext__gettable(lang);
|
||||
}
|
||||
|
||||
tried_lang = 1;
|
||||
}
|
||||
|
||||
if (NULL == table)
|
||||
return (char *) msgid;
|
||||
|
||||
for (i = 0; table[i].msgid; i++) {
|
||||
if (0 == strcmp(table[i].msgid, msgid)) {
|
||||
if (0 == table[i].msgstr)
|
||||
return (char *) msgid;
|
||||
if (0 == table[i].msgstr[0])
|
||||
return (char *) msgid;
|
||||
return table[i].msgstr;
|
||||
}
|
||||
}
|
||||
|
||||
return (char *) msgid;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GETTEXT */
|
||||
|
||||
/* EOF */
|
||||
+24
-17
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Output debugging information.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -39,21 +39,21 @@ void debugging_output(const char *function, const char *file, int line, const ch
|
||||
static FILE *debugfptr = NULL;
|
||||
va_list ap;
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
const struct tm *tm;
|
||||
char tbuf[128]; /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder note: tbuf is only written to by strftime() which
|
||||
* takes its size, and we enforce string termination.
|
||||
* takes its size, and string termination is enforced.
|
||||
*/
|
||||
|
||||
if (false == tried_open) {
|
||||
if (NULL != debug_filename) {
|
||||
debugfptr = fopen(debug_filename, "a"); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder note: caller directly controls
|
||||
* filename, the safest we can manage is to use
|
||||
* append mode.
|
||||
* flawfinder note: the caller directly controls the
|
||||
* filename, so using append mode is the safest
|
||||
* option.
|
||||
*/
|
||||
}
|
||||
tried_open = true;
|
||||
@@ -63,13 +63,22 @@ void debugging_output(const char *function, const char *file, int line, const ch
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note gmtime() is used rather than localtime(). Testing with
|
||||
* "strace" showed many cases where "pv </dev/zero | cat >/dev/null"
|
||||
* being paused and backgrounded would cause pv to be stuck in
|
||||
* futex_wait() inside a pv_sig_alrm() inside a pv_sig_cont(). The
|
||||
* backtrace mentioned many time zone conversion steps, and all of
|
||||
* that goes away with gmtime().
|
||||
*/
|
||||
|
||||
(void) time(&t);
|
||||
tm = localtime(&t);
|
||||
tm = gmtime(&t);
|
||||
tbuf[0] = '\0';
|
||||
if (0 == strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S", tm)) {
|
||||
tbuf[0] = '\0';
|
||||
}
|
||||
tbuf[sizeof(tbuf) - 1] = '\0'; /* enforce termination */
|
||||
tbuf[sizeof(tbuf) - 1] = '\0'; /* enforce termination. */
|
||||
|
||||
(void) fprintf(debugfptr, "[%s] (%d) %s (%s:%d): ", tbuf, getpid(), function, file, line);
|
||||
|
||||
@@ -79,7 +88,7 @@ void debugging_output(const char *function, const char *file, int line, const ch
|
||||
|
||||
/*
|
||||
* flawfinder note: vfprintf format is explicitly controlled by the
|
||||
* caller of this function - no mitigation possible or desirable.
|
||||
* caller of this function - no mitigation is possible or desirable.
|
||||
*/
|
||||
|
||||
(void) fprintf(debugfptr, "\n");
|
||||
@@ -91,7 +100,7 @@ void debugging_output(const char *function, const char *file, int line, const ch
|
||||
/*
|
||||
* Stub debugging destination function.
|
||||
*/
|
||||
void debugging_output_destination( __attribute__((unused))
|
||||
void debugging_output_destination( /*@unused@ */ __attribute__((unused))
|
||||
const char *filename)
|
||||
{
|
||||
}
|
||||
@@ -99,14 +108,12 @@ void debugging_output_destination( __attribute__((unused))
|
||||
/*
|
||||
* Stub debugging output function.
|
||||
*/
|
||||
void debugging_output( __attribute__((unused))
|
||||
const char *function, __attribute__((unused))
|
||||
const char *file, __attribute__((unused))
|
||||
int line, __attribute__((unused))
|
||||
void debugging_output( /*@unused@ */ __attribute__((unused))
|
||||
const char *function, /*@unused@ */ __attribute__((unused))
|
||||
const char *file, /*@unused@ */ __attribute__((unused))
|
||||
int line, /*@unused@ */ __attribute__((unused))
|
||||
const char *format, ...)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* ENABLE_DEBUGGING */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+190
-114
@@ -1,14 +1,15 @@
|
||||
/*
|
||||
* Output command-line help to stdout.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@@ -21,77 +22,26 @@
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of display columns needed to show the given string.
|
||||
*
|
||||
* To do this, we convert it to a wide character string, and use the wide
|
||||
* character display width function "wcswidth()" on it.
|
||||
* Return the number of display columns needed to show the given
|
||||
* null-terminated string.
|
||||
*
|
||||
* If NLS is disabled, or the string cannot be converted, this is just the
|
||||
* same as "strlen()".
|
||||
*/
|
||||
static size_t display_width(const char *string)
|
||||
{
|
||||
size_t width;
|
||||
|
||||
#if defined(ENABLE_NLS) && defined(HAVE_WCHAR_H)
|
||||
size_t wide_char_count;
|
||||
size_t wide_string_buffer_size;
|
||||
wchar_t *wide_string;
|
||||
size_t bytes;
|
||||
|
||||
if (NULL == string)
|
||||
return 0;
|
||||
|
||||
/*@-nullpass@ */
|
||||
bytes = strlen(string); /* flawfinder: ignore */
|
||||
/*
|
||||
* splint note: mbstowcs() manual page on Linux explicitly says it
|
||||
* takes NULL.
|
||||
* flawfinder rationale: it is explicitly required of the caller to
|
||||
* provide a null-terminated string.
|
||||
*/
|
||||
wide_char_count = mbstowcs(NULL, string, 0);
|
||||
/*@+nullpass@ */
|
||||
if (wide_char_count == (size_t) -1) {
|
||||
debug("%s: %s: %s", "mbstowcs", string, strerror(errno));
|
||||
return strlen(string); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: we have already checked for NULL,
|
||||
* and we don't know the size of the originating buffer so
|
||||
* can't use strnlen(); it is up to the caller to provide a
|
||||
* terminated string.
|
||||
*/
|
||||
}
|
||||
|
||||
wide_string_buffer_size = sizeof(*wide_string) * (1 + wide_char_count);
|
||||
wide_string = malloc(wide_string_buffer_size);
|
||||
if (NULL == wide_string) {
|
||||
perror("malloc");
|
||||
return strlen(string); /* flawfinder: ignore */
|
||||
/* flawfinder rationale: see above. */
|
||||
}
|
||||
memset(wide_string, 0, wide_string_buffer_size);
|
||||
|
||||
if (mbstowcs(wide_string, string, 1 + wide_char_count) == (size_t) -1) {
|
||||
debug("%s: %s: %s", "mbstowcs", string, strerror(errno));
|
||||
width = strlen(string); /* flawfinder: ignore */
|
||||
/* flawfinder rationale: see above. */
|
||||
} else if (NULL != wide_string) {
|
||||
/*@-unrecog @ */
|
||||
/* splint seems unable to see the prototype. */
|
||||
width = wcswidth(wide_string, wide_char_count);
|
||||
/*@+unrecog @ */
|
||||
} else {
|
||||
width = 0;
|
||||
}
|
||||
|
||||
free(wide_string);
|
||||
|
||||
#else /* ! defined(ENABLE_NLS) && defined(HAVE_WCHAR_H) */
|
||||
if (NULL == string)
|
||||
return 0;
|
||||
|
||||
width = strlen(string); /* flawfinder: ignore */
|
||||
/* flawfinder rationale: see above. */
|
||||
#endif /* defined(ENABLE_NLS) && defined(HAVE_WCHAR_H) */
|
||||
|
||||
return width;
|
||||
return pv_strwidth(string, bytes);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,95 +49,147 @@ static size_t display_width(const char *string)
|
||||
* The 7-bit ASCII version of display_word_wrap() below - does not
|
||||
* understand multi-byte characters.
|
||||
*/
|
||||
static void display_word_wrap_7bit(const char *string, size_t display_width, size_t left_margin)
|
||||
static void display_word_wrap_7bit(const char *string, size_t display_width, size_t first_line_start,
|
||||
size_t left_margin)
|
||||
{
|
||||
const char *start;
|
||||
const char *end;
|
||||
size_t wrap_at_width;
|
||||
|
||||
if (NULL == string)
|
||||
return;
|
||||
|
||||
start = string;
|
||||
wrap_at_width = display_width;
|
||||
if (wrap_at_width > first_line_start)
|
||||
wrap_at_width -= first_line_start;
|
||||
|
||||
while (strlen(start) > display_width) { /* flawfinder: ignore */
|
||||
/* Wrap lines that are too long. */
|
||||
while (strlen(start) > wrap_at_width) { /* flawfinder: ignore */
|
||||
/* flawfinder rationale: see above. */
|
||||
|
||||
end = start + display_width;
|
||||
/*
|
||||
* Find the last space before the end of the display line,
|
||||
* or if there isn't one, behave as if there was one at the
|
||||
* end of the display line.
|
||||
*/
|
||||
end = start + wrap_at_width;
|
||||
while ((end > start) && (end[0] != ' '))
|
||||
end--;
|
||||
if (end == start) {
|
||||
end = start + display_width;
|
||||
end = start + wrap_at_width;
|
||||
} else {
|
||||
end++;
|
||||
}
|
||||
/* Display the string up to that space. */
|
||||
printf("%.*s", (int) (end - start), start);
|
||||
if (end == start)
|
||||
end++;
|
||||
start = end;
|
||||
if (start[0] != '\0')
|
||||
/*
|
||||
* If there's more text left, start a new display line and
|
||||
* pad it with spaces to the left margin, and change the
|
||||
* wrap width to the display width minus the left margin.
|
||||
*/
|
||||
if (start[0] != '\0') {
|
||||
printf("\n%*s", (int) left_margin, "");
|
||||
if (display_width > left_margin) {
|
||||
wrap_at_width = display_width - left_margin;
|
||||
} else {
|
||||
wrap_at_width = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Display the remainder of the string. */
|
||||
printf("%s", start);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Output a string to standard output, word wrapping to "display_width"
|
||||
* display character positions, and left-padding any new lines after the
|
||||
* first one with "left_margin" spaces.
|
||||
* Output a null-terminated string to standard output, word wrapping to
|
||||
* "display_width" display character positions, assuming that the first line
|
||||
* starts with the cursor already at "first_line_start" display character
|
||||
* positions from the left, and left-padding any new lines after the first
|
||||
* one with "left_margin" spaces.
|
||||
*
|
||||
* Wide characters are handled if NLS is enabled, but if they can't be, this
|
||||
* falls back to a version which just counts bytes as characters.
|
||||
*/
|
||||
static void display_word_wrap(const char *string, size_t display_width, size_t left_margin)
|
||||
static void display_word_wrap(const char *string, size_t display_width, size_t first_line_start, size_t left_margin)
|
||||
{
|
||||
#if defined(ENABLE_NLS) && defined(HAVE_WCHAR_H)
|
||||
size_t wrap_at_width;
|
||||
size_t wide_char_count;
|
||||
size_t wide_string_buffer_size;
|
||||
wchar_t *wide_string;
|
||||
size_t start_idx, end_idx, chars_remaining;
|
||||
size_t start_idx, chars_remaining;
|
||||
|
||||
debug("[%s], display_width=%d, first_line_start=%d, left_margin=%d", string, (int) display_width,
|
||||
(int) first_line_start, (int) left_margin);
|
||||
|
||||
if (NULL == string)
|
||||
return;
|
||||
|
||||
/* Calculate how many wide characters are in the multibyte string. */
|
||||
|
||||
/*@-nullpass@ */
|
||||
/* splint note: see earlier mbstowcs() call. */
|
||||
/* splint note: see mbstowcs() call in pv_strwidth(). */
|
||||
wide_char_count = mbstowcs(NULL, string, 0);
|
||||
/*@+nullpass@ */
|
||||
if (wide_char_count == (size_t) -1) {
|
||||
debug("%s: %s: %s", "mbstowcs", string, strerror(errno));
|
||||
display_word_wrap_7bit(string, display_width, left_margin);
|
||||
display_word_wrap_7bit(string, display_width, first_line_start, left_margin);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a buffer in which to convert the multibyte string to a
|
||||
* wide-character string, plus one character for zero padding.
|
||||
*/
|
||||
|
||||
wide_string_buffer_size = sizeof(*wide_string) * (1 + wide_char_count);
|
||||
wide_string = malloc(wide_string_buffer_size);
|
||||
if (NULL == wide_string) {
|
||||
perror("malloc");
|
||||
display_word_wrap_7bit(string, display_width, left_margin);
|
||||
display_word_wrap_7bit(string, display_width, first_line_start, left_margin);
|
||||
return;
|
||||
}
|
||||
memset(wide_string, 0, wide_string_buffer_size);
|
||||
|
||||
/* Convert the multibyte string to a wide-character string. */
|
||||
|
||||
if (mbstowcs(wide_string, string, 1 + wide_char_count) == (size_t) -1) {
|
||||
debug("%s: %s: %s", "mbstowcs", string, strerror(errno));
|
||||
free(wide_string);
|
||||
display_word_wrap_7bit(string, display_width, left_margin);
|
||||
display_word_wrap_7bit(string, display_width, first_line_start, left_margin);
|
||||
return;
|
||||
}
|
||||
|
||||
start_idx = 0;
|
||||
wrap_at_width = display_width;
|
||||
if (wrap_at_width > first_line_start)
|
||||
wrap_at_width -= first_line_start;
|
||||
chars_remaining = wide_char_count;
|
||||
|
||||
while (chars_remaining > 0 && wcswidth(&(wide_string[start_idx]), chars_remaining) > display_width) {
|
||||
size_t next_idx;
|
||||
/* Wrap lines that are too long. */
|
||||
|
||||
end_idx = start_idx + display_width;
|
||||
/*@-unrecog@ *//* splint doesn't see the prototype for wcswidth(). */
|
||||
while (chars_remaining > 0 && wcswidth(&(wide_string[start_idx]), chars_remaining) > (int) wrap_at_width) {
|
||||
/*@+unrecog@ */
|
||||
size_t next_idx, end_idx;
|
||||
|
||||
/*
|
||||
* Find the last space before the end of the display line,
|
||||
* or if there isn't one, behave as if there was one at the
|
||||
* end of the display line.
|
||||
*/
|
||||
|
||||
end_idx = start_idx + wrap_at_width;
|
||||
while ((end_idx > start_idx) && (!iswspace(wide_string[end_idx])))
|
||||
end_idx--;
|
||||
if (end_idx == start_idx) {
|
||||
end_idx = start_idx + display_width;
|
||||
end_idx = start_idx + wrap_at_width;
|
||||
} else {
|
||||
end_idx++;
|
||||
}
|
||||
@@ -196,12 +198,13 @@ static void display_word_wrap(const char *string, size_t display_width, size_t l
|
||||
if (end_idx == start_idx)
|
||||
next_idx++;
|
||||
|
||||
/* Display the string up to that space, a character at a time. */
|
||||
while (start_idx < end_idx && start_idx < wide_char_count) {
|
||||
char multi_byte_string[MB_CUR_MAX + 1]; /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: array is explicitly
|
||||
* flawfinder rationale: the array is explicitly
|
||||
* cleared, large enough according to the wctomb()
|
||||
* manual, and we explicitly terminate the string.
|
||||
* manual, and the string is explicitly terminated.
|
||||
*/
|
||||
memset(multi_byte_string, 0, MB_CUR_MAX + 1);
|
||||
if (wctomb(multi_byte_string, wide_string[start_idx]) >= 0) {
|
||||
@@ -212,12 +215,26 @@ static void display_word_wrap(const char *string, size_t display_width, size_t l
|
||||
}
|
||||
|
||||
start_idx = next_idx;
|
||||
if (start_idx < wide_char_count)
|
||||
/*
|
||||
* If there's more text left, start a new display line and
|
||||
* pad it with spaces to the left margin, and change the
|
||||
* wrap width to the display width minus the left margin.
|
||||
*/
|
||||
if (start_idx < wide_char_count) {
|
||||
printf("\n%*s", (int) left_margin, "");
|
||||
|
||||
chars_remaining = wide_char_count - start_idx;
|
||||
if (display_width > left_margin) {
|
||||
wrap_at_width = display_width - left_margin;
|
||||
} else {
|
||||
wrap_at_width = 1;
|
||||
}
|
||||
chars_remaining = wide_char_count - start_idx;
|
||||
} else {
|
||||
/* Explicitly set to 0 to avoid underflow. */
|
||||
chars_remaining = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Display the remainder of the string, a character at a time. */
|
||||
while (start_idx < wide_char_count) {
|
||||
char multi_byte_string[MB_CUR_MAX + 1]; /* flawfinder: ignore */
|
||||
/* flawfinder rationale as above. */
|
||||
@@ -232,7 +249,7 @@ static void display_word_wrap(const char *string, size_t display_width, size_t l
|
||||
free(wide_string);
|
||||
|
||||
#else /* ! defined(ENABLE_NLS) && defined(HAVE_WCHAR_H) */
|
||||
display_word_wrap_7bit(string, display_width, left_margin);
|
||||
display_word_wrap_7bit(string, display_width, first_line_start, left_margin);
|
||||
#endif /* defined(ENABLE_NLS) && defined(HAVE_WCHAR_H) */
|
||||
}
|
||||
|
||||
@@ -297,15 +314,9 @@ void display_help(void)
|
||||
{ "-a", "--average-rate", NULL,
|
||||
N_("show data transfer average rate counter"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-m", "--average-rate-window", N_("SEC"),
|
||||
N_("compute average rate over past SEC seconds (default 30s)"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-b", "--bytes", NULL,
|
||||
N_("show number of bytes transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-8", "--bits", NULL,
|
||||
N_("show number of bits transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-T", "--buffer-percent", NULL,
|
||||
N_("show percentage of transfer buffer in use"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -322,6 +333,12 @@ void display_help(void)
|
||||
N_("do not output any transfer information at all"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-8", "--bits", NULL,
|
||||
N_("show number of bits transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-k", "--si", NULL,
|
||||
N_("treat suffixes as multiples of 1000 rather than 1024"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-W", "--wait", NULL,
|
||||
N_("display nothing until first byte transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -331,6 +348,9 @@ void display_help(void)
|
||||
{ "-s", "--size", N_("SIZE"),
|
||||
N_("set estimated data size to SIZE bytes"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-g", "--gauge", NULL,
|
||||
N_("if size unknown, show rate vs max rate"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-l", "--line-mode", NULL,
|
||||
N_("count lines instead of bytes"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -340,6 +360,9 @@ void display_help(void)
|
||||
{ "-i", "--interval", N_("SEC"),
|
||||
N_("update every SEC seconds"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-m", "--average-rate-window", N_("SEC"),
|
||||
N_("compute average rate over past SEC seconds (default 30s)"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-w", "--width", N_("WIDTH"),
|
||||
N_("assume terminal is WIDTH characters wide"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -349,6 +372,18 @@ void display_help(void)
|
||||
{ "-N", "--name", N_("NAME"),
|
||||
N_("prefix visual information with NAME"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-u", "--bar-style", N_("STYLE"),
|
||||
N_("set default bar style to STYLE"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-x", "--extra-display", N_("SPEC"),
|
||||
N_("also send progress to SPEC"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-9", "--conemu", NULL,
|
||||
N_("set terminal progress state with OSC 9;4 (ConEmu)"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-v", "--stats", NULL,
|
||||
N_("output transfer statistics at the end"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-f", "--force", NULL,
|
||||
N_("output even if standard error is not a terminal"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -356,6 +391,9 @@ void display_help(void)
|
||||
N_("use cursor positioning escape sequences"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-o", "--output", N_("FILE"),
|
||||
N_("write output to FILE instead of stdout"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-L", "--rate-limit", N_("RATE"),
|
||||
N_("limit transfer to RATE bytes per second"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -365,9 +403,15 @@ void display_help(void)
|
||||
{ "-C", "--no-splice", NULL,
|
||||
N_("never use splice(), always use read/write"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-J", "--pipe-buffer-size", N_("BYTES"),
|
||||
N_("set the pipe buffer size to BYTES"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-E", "--skip-errors", NULL,
|
||||
N_("skip read errors in input"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-Z", "--error-skip-block", N_("BYTES"),
|
||||
N_("skip errors in BYTES blocks at a time"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-S", "--stop-at-size", NULL,
|
||||
N_("stop after --size bytes have been transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -377,20 +421,34 @@ void display_help(void)
|
||||
{ "-K", "--direct-io", NULL,
|
||||
N_("use direct I/O to bypass cache"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#ifdef HAVE_IPC
|
||||
{ "-O", "--sparse", NULL,
|
||||
N_("try to seek instead of writing null bytes"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-X", "--discard", NULL,
|
||||
N_("discard input instead of writing to output"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-U", "--store-and-forward", N_("FILE"),
|
||||
N_("write all input to FILE before writing to output"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-d", "--watchfd", N_("PID[:FD]|=NAME|@LISTFILE"),
|
||||
N_("watch file FD opened by process PID"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#ifdef PV_REMOTE_CONTROL
|
||||
{ "-R", "--remote", N_("PID"),
|
||||
N_("update settings of process PID"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#endif /* HAVE_IPC */
|
||||
{ "-Q", "--query", N_("PID"),
|
||||
N_("show progress of process PID"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#endif /* PV_REMOTE_CONTROL */
|
||||
{ "-M", "--monitor", "in|0|out|1|both|2",
|
||||
N_("run a command and monitor its standard input, output, or both"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-P", "--pidfile", N_("FILE"),
|
||||
N_("save process ID in FILE"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-d", "--watchfd", N_("PID[:FD]"),
|
||||
N_("watch file FD opened by process PID"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-h", "--help", NULL,
|
||||
N_("show this help and exit"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -411,6 +469,7 @@ void display_help(void)
|
||||
size_t right_margin = 77;
|
||||
const char *program_description;
|
||||
const char *bug_report_note;
|
||||
char *format_sequences = NULL;
|
||||
unsigned int terminal_width = 0, terminal_height = 0;
|
||||
|
||||
pv_screensize(&terminal_width, &terminal_height);
|
||||
@@ -424,7 +483,7 @@ void display_help(void)
|
||||
* be hard to exploit - the message catalogue would have to be
|
||||
* replaced or forced to load from another location.
|
||||
*/
|
||||
printf(_("Usage: %s [OPTION] [FILE]..."), PROGRAM_NAME);
|
||||
printf(_("Usage: %s [OPTION] [FILE]..."), PACKAGE_NAME);
|
||||
/*@+formatconst@ */
|
||||
|
||||
printf("\n");
|
||||
@@ -433,11 +492,11 @@ void display_help(void)
|
||||
/*
|
||||
* splint note: the gettext calls made by _() cause memory leak
|
||||
* warnings, but in this case it's unavoidable, and mitigated by the
|
||||
* fact we only translate each string once.
|
||||
* fact that each string is only translated once.
|
||||
*/
|
||||
program_description = _("Concatenate FILE(s), or standard input, to standard output, with monitoring.");
|
||||
if (NULL != program_description) {
|
||||
display_word_wrap(program_description, right_margin, 0);
|
||||
display_word_wrap(program_description, right_margin, 0, 0);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -447,8 +506,8 @@ void display_help(void)
|
||||
* Translate the help text, and calculate the displayed width of
|
||||
* each part of each option definition. The total display width of
|
||||
* the short option, long option, and option argument together form
|
||||
* the "option" width - we look for the widest one to calculate the
|
||||
* left margin for all of the descriptions to start at.
|
||||
* the "option" width. The widest one is used to calculate the left
|
||||
* margin for all of the descriptions to start at.
|
||||
*/
|
||||
for (option_index = 0; NULL != option_definitions[option_index].opt_short; option_index++) {
|
||||
struct option_definition_s *definition;
|
||||
@@ -492,7 +551,8 @@ void display_help(void)
|
||||
*
|
||||
* " <short>, <long> <arg> <description>"
|
||||
*
|
||||
* If we don't have getopt_long() then ", <long>" is omitted.
|
||||
* If getopt_long() is unavailable then ", <long>" is
|
||||
* omitted.
|
||||
*/
|
||||
option_width += 2 + definition->width.opt_short; /* " short" */
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
@@ -510,9 +570,12 @@ void display_help(void)
|
||||
* Set the left margin for the option descriptions, based on the
|
||||
* widest option width, or (right margin - min_description_width),
|
||||
* whichever is less, so that there is always room for
|
||||
* "min_description_width" characters of description.
|
||||
* "min_description_width" characters of description. If there's
|
||||
* not even room for that, set the left margin to 2.
|
||||
*/
|
||||
description_left_margin = right_margin - min_description_width;
|
||||
description_left_margin = 2;
|
||||
if (right_margin > (min_description_width + 2))
|
||||
description_left_margin = right_margin - min_description_width;
|
||||
if (widest_option_width < description_left_margin) {
|
||||
description_left_margin = widest_option_width;
|
||||
}
|
||||
@@ -553,37 +616,50 @@ void display_help(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* If the option is too wide, start a new line for the
|
||||
* description. In both cases, pad with spaces up to the
|
||||
* description left margin.
|
||||
* If the option (with 2 trailing spaces) is too wide, start
|
||||
* a new line for the description. Either way, pad with
|
||||
* spaces up to the description left margin.
|
||||
*/
|
||||
if (option_width > description_left_margin) {
|
||||
if ((option_width + 2) > description_left_margin) {
|
||||
printf("\n%*s", (int) description_left_margin, "");
|
||||
} else if (option_width < description_left_margin) {
|
||||
printf("%*s", (int) (description_left_margin - option_width), "");
|
||||
}
|
||||
|
||||
/* Output the description, word wrapped. */
|
||||
display_word_wrap(definition->opt_description, right_margin - description_left_margin,
|
||||
display_word_wrap(definition->opt_description, right_margin, description_left_margin,
|
||||
description_left_margin);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
format_sequences = pv_format_sequences();
|
||||
if (NULL != format_sequences) {
|
||||
const char *format_sequence_header;
|
||||
format_sequence_header = _("Supported format sequences:");
|
||||
if (NULL != format_sequence_header) {
|
||||
printf("\n");
|
||||
display_word_wrap(format_sequence_header, right_margin, 0, 0);
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n ");
|
||||
display_word_wrap(format_sequences, right_margin, 2, 2);
|
||||
free(format_sequences);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
bug_report_note = _("Please report any bugs to %s.");
|
||||
bug_report_note = _("Please report any bugs to: %s");
|
||||
if (NULL != bug_report_note) {
|
||||
/*@-formatconst@ */
|
||||
/*
|
||||
* splint note: see earlier "formatconst" note.
|
||||
* flawfinder: same reason.
|
||||
*/
|
||||
printf(bug_report_note, BUG_REPORTS_TO); /* flawfinder: ignore */
|
||||
printf(bug_report_note, PACKAGE_BUGREPORT); /* flawfinder: ignore */
|
||||
/*@+formatconst@ */
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+838
-158
File diff suppressed because it is too large
Load Diff
+1036
-90
File diff suppressed because it is too large
Load Diff
@@ -1,324 +0,0 @@
|
||||
/*
|
||||
* Remote-control functions.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "options.h"
|
||||
#include "pv.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
struct remote_msg {
|
||||
long mtype;
|
||||
bool progress; /* progress bar flag */
|
||||
bool timer; /* timer flag */
|
||||
bool eta; /* ETA flag */
|
||||
bool fineta; /* absolute ETA flag */
|
||||
bool rate; /* rate counter flag */
|
||||
bool average_rate; /* average rate counter flag */
|
||||
bool bytes; /* bytes transferred flag */
|
||||
bool bufpercent; /* transfer buffer percentage flag */
|
||||
unsigned int lastwritten; /* last-written bytes count */
|
||||
unsigned long long rate_limit; /* rate limit, in bytes per second */
|
||||
unsigned long long buffer_size; /* buffer size, in bytes (0=default) */
|
||||
unsigned long long size; /* total size of data */
|
||||
double interval; /* interval between updates */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
char name[256];
|
||||
char format[256];
|
||||
};
|
||||
|
||||
|
||||
static int remote__msgid = -1;
|
||||
|
||||
|
||||
/*
|
||||
* Return a key for use with msgget() which will be unique to the current
|
||||
* user.
|
||||
*
|
||||
* We can't just use ftok() because the queue needs to be user-specific
|
||||
* so that a user cannot send messages to another user's process, and we
|
||||
* can't easily find out the terminal a given process is connected to in a
|
||||
* cross-platform way.
|
||||
*/
|
||||
static key_t remote__genkey(void)
|
||||
{
|
||||
uid_t uid;
|
||||
key_t key;
|
||||
|
||||
uid = geteuid();
|
||||
|
||||
key = ftok("/tmp", (int) 'P') | uid;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a message queue ID that is unique to the current user and the
|
||||
* given process ID, or -1 on error.
|
||||
*/
|
||||
static int remote__msgget(void)
|
||||
{
|
||||
/* Catch SIGSYS in case msgget() raises it, so we get ENOSYS */
|
||||
(void) signal(SIGSYS, SIG_IGN);
|
||||
return msgget(remote__genkey(), IPC_CREAT | 0600);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the options of a remote process by setting up an IPC message queue,
|
||||
* sending a message containing the new options, and then waiting for the
|
||||
* message to be consumed by the remote process.
|
||||
*
|
||||
* Returns nonzero on error.
|
||||
*/
|
||||
int pv_remote_set(opts_t opts)
|
||||
{
|
||||
struct remote_msg msgbuf;
|
||||
struct msqid_ds qbuf;
|
||||
long timeout;
|
||||
int msgid;
|
||||
unsigned long initial_qnum;
|
||||
|
||||
/*
|
||||
* Check that the remote process exists.
|
||||
*/
|
||||
if (kill((pid_t) (opts->remote), 0) != 0) {
|
||||
fprintf(stderr, "%s: %u: %s\n", opts->program_name, opts->remote, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure parameters are within sensible bounds.
|
||||
*/
|
||||
if (opts->width < 1)
|
||||
opts->width = 80;
|
||||
if (opts->height < 1)
|
||||
opts->height = 25;
|
||||
if (opts->width > 999999)
|
||||
opts->width = 999999;
|
||||
if (opts->height > 999999)
|
||||
opts->height = 999999;
|
||||
if ((opts->interval > 0) && (opts->interval < 0.1))
|
||||
opts->interval = 0.1;
|
||||
if (opts->interval > 600)
|
||||
opts->interval = 600;
|
||||
|
||||
/*
|
||||
* Copy parameters into message buffer.
|
||||
*/
|
||||
memset(&msgbuf, 0, sizeof(msgbuf));
|
||||
msgbuf.mtype = (long) (opts->remote);
|
||||
msgbuf.progress = opts->progress;
|
||||
msgbuf.timer = opts->timer;
|
||||
msgbuf.eta = opts->eta;
|
||||
msgbuf.fineta = opts->fineta;
|
||||
msgbuf.rate = opts->rate;
|
||||
msgbuf.average_rate = opts->average_rate;
|
||||
msgbuf.bytes = opts->bytes;
|
||||
msgbuf.bufpercent = opts->bufpercent;
|
||||
msgbuf.lastwritten = opts->lastwritten;
|
||||
msgbuf.rate_limit = opts->rate_limit;
|
||||
msgbuf.buffer_size = opts->buffer_size;
|
||||
msgbuf.size = opts->size;
|
||||
msgbuf.interval = opts->interval;
|
||||
msgbuf.width = opts->width;
|
||||
msgbuf.height = opts->height;
|
||||
if (opts->name != NULL) {
|
||||
strncpy(msgbuf.name, opts->name, sizeof(msgbuf.name) - 1);
|
||||
}
|
||||
if (opts->format != NULL) {
|
||||
strncpy(msgbuf.format, opts->format, sizeof(msgbuf.format) - 1);
|
||||
}
|
||||
|
||||
msgid = remote__msgget();
|
||||
if (msgid < 0) {
|
||||
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&qbuf, 0, sizeof(qbuf));
|
||||
if (msgctl(msgid, IPC_STAT, &qbuf) < 0) {
|
||||
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
initial_qnum = qbuf.msg_qnum;
|
||||
|
||||
if (msgsnd(msgid, &msgbuf, sizeof(msgbuf) - sizeof(long), 0) != 0) {
|
||||
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
timeout = 1100000;
|
||||
|
||||
while (timeout > 10000) {
|
||||
struct timeval tv;
|
||||
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
(void) select(0, NULL, NULL, NULL, &tv);
|
||||
timeout -= 10000;
|
||||
|
||||
/*
|
||||
* If we can't stat the queue, it must have been deleted.
|
||||
*/
|
||||
memset(&qbuf, 0, sizeof(qbuf));
|
||||
if (msgctl(msgid, IPC_STAT, &qbuf) < 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If the message count is at or below the message count
|
||||
* before we sent our message, assume it was received.
|
||||
*/
|
||||
if (qbuf.msg_qnum <= initial_qnum) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Message not received - delete it.
|
||||
*/
|
||||
memset(&qbuf, 0, sizeof(qbuf));
|
||||
if (msgctl(msgid, IPC_STAT, &qbuf) >= 0) {
|
||||
(void) msgrcv(msgid, &msgbuf, sizeof(msgbuf) - sizeof(long), (long) (opts->remote), IPC_NOWAIT);
|
||||
/*
|
||||
* If this leaves nothing on the queue, remove the
|
||||
* queue, in case we created one for no reason.
|
||||
*/
|
||||
if (msgctl(msgid, IPC_STAT, &qbuf) >= 0) {
|
||||
if (qbuf.msg_qnum < 1)
|
||||
(void) msgctl(msgid, IPC_RMID, &qbuf);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: %u: %s\n", opts->program_name, opts->remote, _("message not received"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for an IPC remote handling message and, if there is one, replace
|
||||
* the current process's options with those being passed in.
|
||||
*
|
||||
* NB relies on pv_state_set_format() causing the output format to be
|
||||
* reparsed.
|
||||
*/
|
||||
void pv_remote_check(pvstate_t state)
|
||||
{
|
||||
struct remote_msg msgbuf;
|
||||
ssize_t got;
|
||||
|
||||
if (remote__msgid < 0)
|
||||
return;
|
||||
|
||||
memset(&msgbuf, 0, sizeof(msgbuf));
|
||||
|
||||
got = msgrcv(remote__msgid, &msgbuf, sizeof(msgbuf) - sizeof(long), getpid(), IPC_NOWAIT);
|
||||
if (got < 0) {
|
||||
/*
|
||||
* If our queue had been deleted, re-create it.
|
||||
*/
|
||||
if (errno != EAGAIN && errno != ENOMSG) {
|
||||
remote__msgid = remote__msgget();
|
||||
}
|
||||
}
|
||||
if (got < 1)
|
||||
return;
|
||||
|
||||
debug("%s", "received remote message");
|
||||
|
||||
pv_state_format_string_set(state, NULL);
|
||||
pv_state_name_set(state, NULL);
|
||||
|
||||
pv_state_set_format(state, msgbuf.progress, msgbuf.timer,
|
||||
msgbuf.eta, msgbuf.fineta, msgbuf.rate,
|
||||
msgbuf.average_rate,
|
||||
msgbuf.bytes, msgbuf.bufpercent,
|
||||
msgbuf.lastwritten, '\0' == msgbuf.name[0] ? NULL : strdup(msgbuf.name));
|
||||
|
||||
if (msgbuf.rate_limit > 0)
|
||||
pv_state_rate_limit_set(state, msgbuf.rate_limit);
|
||||
if (msgbuf.buffer_size > 0) {
|
||||
pv_state_target_buffer_size_set(state, msgbuf.buffer_size);
|
||||
}
|
||||
if (msgbuf.size > 0)
|
||||
pv_state_size_set(state, msgbuf.size);
|
||||
if (msgbuf.interval > 0)
|
||||
pv_state_interval_set(state, msgbuf.interval);
|
||||
if (msgbuf.width > 0)
|
||||
pv_state_width_set(state, msgbuf.width);
|
||||
if (msgbuf.height > 0)
|
||||
pv_state_height_set(state, msgbuf.height);
|
||||
if (msgbuf.format[0] != '\0')
|
||||
pv_state_format_string_set(state, strdup(msgbuf.format));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialise remote message reception handling.
|
||||
*/
|
||||
void pv_remote_init(void)
|
||||
{
|
||||
remote__msgid = remote__msgget();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clean up after remote message reception handling.
|
||||
*/
|
||||
void pv_remote_fini(void)
|
||||
{
|
||||
if (remote__msgid >= 0) {
|
||||
struct msqid_ds qbuf;
|
||||
memset(&qbuf, 0, sizeof(qbuf));
|
||||
(void) msgctl(remote__msgid, IPC_RMID, &qbuf);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !HAVE_IPC */
|
||||
|
||||
/*
|
||||
* Dummy stubs for remote control when we don't have IPC.
|
||||
*/
|
||||
void pv_remote_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pv_remote_check(pvstate_t state)
|
||||
{
|
||||
}
|
||||
|
||||
void pv_remote_fini(void)
|
||||
{
|
||||
}
|
||||
|
||||
int pv_remote_set(pvstate_t state)
|
||||
{
|
||||
fprintf(stderr, "%s\n", _("IPC not supported on this system"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
/* EOF */
|
||||
+11
-13
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Output version information to stdout.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -18,18 +18,16 @@ void display_version(void)
|
||||
/*
|
||||
* splint note: the gettext calls made by _() cause memory leak
|
||||
* warnings, but in this case it's unavoidable, and mitigated by the
|
||||
* fact we only translate each string once.
|
||||
* fact that each string is only translated once.
|
||||
*/
|
||||
/* GNU standard first line format: program and version only */
|
||||
printf("%s %s\n", PROGRAM_NAME, VERSION);
|
||||
/* GNU standard second line format - "Copyright" always in English */
|
||||
printf("Copyright %s %s\n", COPYRIGHT_YEAR, COPYRIGHT_HOLDER);
|
||||
/* GNU standard license line and free software notice */
|
||||
printf("%s\n", _("License: Artistic v2.0 <https://opensource.org/license/artistic-2-0/>"));
|
||||
/* GNU standard first line format: program and version only. */
|
||||
printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
/* GNU standard second line format - "Copyright" always in English. */
|
||||
printf("Copyright %s %s\n", "2026", "Andrew Wood");
|
||||
/* GNU standard license line and free software notice. */
|
||||
printf("%s\n", _("License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"));
|
||||
printf("%s\n", _("This is free software: you are free to change and redistribute it."));
|
||||
printf("%s\n", _("There is NO WARRANTY, to the extent permitted by law."));
|
||||
/* Project web site link */
|
||||
printf("\n%s: <%s>\n", _("Project web site"), PROJECT_HOMEPAGE);
|
||||
/* Project web site link. */
|
||||
printf("\n%s: <%s>\n", _("Project web site"), PACKAGE_URL);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
-509
@@ -1,509 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-07-30 19:07+0100\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
"From: Andrew Wood <ivarch@ubik>\n"
|
||||
"Xgettext-Options: --default-domain=pkgbuild --directory=./.pkgdir --add-"
|
||||
"comments --keyword=_ --keyword=N_\n"
|
||||
"Files: src/getopt/getopt.c src/getopt/getopt1.c src/version.c src/main/init."
|
||||
"c src/main/help.c src/main/xpmptr.c src/guts/load.c src/guts/stop.c src/guts/"
|
||||
"configure.c src/guts/make.c src/guts/install.c src/guts/prefs.c src/ui/"
|
||||
"generate.c src/ui/main.c src/ui/xpm.c src/ui/status.c src/ui/activate.c src/"
|
||||
"ui/handlers/main.c src/ui/handlers/package.c src/ui/handlers/prefs.c src/ui/"
|
||||
"handlers/dirsel.c src/ui/handlers/popup.c src/ui/handlers/help.c src/ui/"
|
||||
"textout.c src/ui/report.c src/ui/callback.c src/nls/intl/bindtextdom.c src/"
|
||||
"nls/intl/dcgettext.c src/nls/intl/dgettext.c src/nls/intl/finddomain.c src/"
|
||||
"nls/intl/gettext.c src/nls/intl/loadmsgcat.c src/nls/intl/localealias.c src/"
|
||||
"nls/intl/textdomain.c src/nls/intl-cat/cat-compat.c src/nls/intl-gett/intl-"
|
||||
"compat.c\n"
|
||||
|
||||
#: src/pv/cursor.c:85
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "Terminalname konnte nicht gelesen werden"
|
||||
|
||||
#: src/pv/cursor.c:117
|
||||
msgid "failed to open lock file"
|
||||
msgstr "Sperrdatei konnte nicht geöffnet werden"
|
||||
|
||||
#: src/pv/cursor.c:150
|
||||
msgid "lock attempt failed"
|
||||
msgstr "Sperrversuch fehlgeschlagen"
|
||||
|
||||
#: src/pv/cursor.c:391
|
||||
msgid "failed to open terminal"
|
||||
msgstr "Terminal konnte nicht geöffnet werden"
|
||||
|
||||
#: src/pv/file.c:119
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "Konnte nicht versuchen, die Ausgabe zu starten"
|
||||
|
||||
#: src/pv/file.c:210
|
||||
msgid "failed to close file"
|
||||
msgstr "Datei konnte nicht geschlossen werden"
|
||||
|
||||
#: src/pv/file.c:232
|
||||
msgid "failed to read file"
|
||||
msgstr "Datei konnte nicht gelesen werden"
|
||||
|
||||
#: src/pv/file.c:239 src/main/options.c:284
|
||||
msgid "failed to stat file"
|
||||
msgstr "Dateiinformationen konnten nicht gelesen werden"
|
||||
|
||||
#: src/pv/file.c:246
|
||||
msgid "failed to stat output file"
|
||||
msgstr "Dateiinformationen für Ausgabe-Datei konnten nicht gelesen werden"
|
||||
|
||||
#: src/pv/file.c:268
|
||||
msgid "input file is output file"
|
||||
msgstr "Eingabe-Datei ist Ausgabe-Datei"
|
||||
|
||||
#: src/pv/transfer.c:359
|
||||
msgid "read failed"
|
||||
msgstr "read-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:374
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "warnung: lesefehler erkannt"
|
||||
|
||||
#: src/pv/transfer.c:386
|
||||
msgid "file is not seekable"
|
||||
msgstr "datei ist nicht durchsuchbar"
|
||||
|
||||
#: src/pv/transfer.c:445
|
||||
msgid "failed to seek past error"
|
||||
msgstr "konnte den Fehler nicht überwinden"
|
||||
|
||||
#: src/pv/transfer.c:461
|
||||
msgid "skipped past read error"
|
||||
msgstr "über den Lesefehler hinaus verschoben"
|
||||
|
||||
#: src/pv/transfer.c:461 src/pv/display.c:660
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/transfer.c:617
|
||||
msgid "write failed"
|
||||
msgstr "write-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:736 src/pv/display.c:594
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "Puffer konnte nicht allokiert werden"
|
||||
|
||||
#.
|
||||
#. * Any other error is a problem and we must report back.
|
||||
#.
|
||||
#: src/pv/transfer.c:833
|
||||
msgid "select call failed"
|
||||
msgstr "select-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/watchpid.c:73 src/pv/watchpid.c:83 src/pv/watchpid.c:94
|
||||
#: src/pv/watchpid.c:102 src/pv/watchpid.c:139 src/pv/watchpid.c:150
|
||||
#: src/pv/watchpid.c:158 src/pv/watchpid.c:169 src/pv/watchpid.c:253
|
||||
#: src/pv/watchpid.c:261 src/pv/watchpid.c:292 src/pv/watchpid.c:312
|
||||
#: src/pv/loop.c:506 src/pv/loop.c:558 src/pv/loop.c:602
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:95 src/pv/watchpid.c:104
|
||||
#: src/pv/watchpid.c:150 src/pv/watchpid.c:159 src/pv/watchpid.c:171
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:104 src/pv/watchpid.c:171
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "keine normale Datei oder Blockgerät"
|
||||
|
||||
#: src/pv/state.c:30
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:59
|
||||
msgid "none"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:159
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:164
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:656
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:711 src/pv/display.c:722
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "B/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:762 src/pv/display.c:766 src/pv/display.c:825
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#. GNU standard license line and free software notice
|
||||
#: src/main/version.c:28
|
||||
msgid "License: Artistic v2.0 <https://opensource.org/license/artistic-2-0/>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#. Project web site link
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:215
|
||||
msgid "message not received"
|
||||
msgstr "Nachricht nicht empfangen"
|
||||
|
||||
#: src/main/remote.c:318
|
||||
msgid "IPC not supported on this system"
|
||||
msgstr "IPC wird auf diesem System nicht unterstützt"
|
||||
|
||||
#: src/main/help.c:283
|
||||
msgid "show progress bar"
|
||||
msgstr "Fortschritts-Anzeige"
|
||||
|
||||
#: src/main/help.c:286
|
||||
msgid "show elapsed time"
|
||||
msgstr "zeige die verstrichene Zeit an"
|
||||
|
||||
#: src/main/help.c:289
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "zeige die erwartete Zeit bis zum Ende an"
|
||||
|
||||
#: src/main/help.c:292
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "zeige die absolute geschätzte Zeit bis zur Fertigstellung"
|
||||
|
||||
#: src/main/help.c:295
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "zeige die Datentransferrate an"
|
||||
|
||||
#: src/main/help.c:298
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:300 src/main/help.c:328 src/main/help.c:340
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:301
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:304
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "zeige die Anzahl von Bytes, die transferiert worden sind"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "zeige, wie viel Prozent des Übertragungsbuffers in Benutzung sind"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:313
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "NUM zeige die zuletzt geschriebenen NUM Bytes"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:316
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "setze das Ausgabeformat auf FORMAT"
|
||||
|
||||
#: src/main/help.c:319
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "Ausgabe von Prozent-Angaben statt visueller Darstellung"
|
||||
|
||||
#: src/main/help.c:322
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "sämtliche Transferinformationen unterdrücken"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "keine Ausgabe bevor das erste Byte übertragen wurde"
|
||||
|
||||
#: src/main/help.c:329
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "SEC nichts anzeigen, bis SEC Sekunden vergangen sind"
|
||||
|
||||
#: src/main/help.c:331
|
||||
msgid "SIZE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "setze erwartete Datenlänge auf SIZE Byte"
|
||||
|
||||
#: src/main/help.c:335
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "zähle Zeilen anstelle von Bytes"
|
||||
|
||||
#: src/main/help.c:338
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "Zeilen sind nullterminiert"
|
||||
|
||||
#: src/main/help.c:341
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualisiere Ausgabe nach SEC Sekunden Intervall"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:344
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "setze Terminal-Breite auf WIDTH Zeichen"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:347
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "setze Terminal-Höhe auf HEIGHT Zeichen"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "setze den NAMEn für visuelle Darstellung"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
"Ausgabe auch dann erzwingen, wenn der Fehlerausgabe-Kanal kein Terminal ist"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "benutze Escape-Sequenzen zur Cursor-Positionierung"
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "beschränke die Transferrate auf RATE Byte pro Sekunde"
|
||||
|
||||
#: src/main/help.c:362
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "BYTES benutze einen Puffer in der Größe von BYTES"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "anstelle von splice() immer read/write benutzen"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "skip read errors in input"
|
||||
msgstr "Lesefehler in der Eingabe nicht beachten"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "anhalten, nachdem --size Bytes übertragen wurden"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:381
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "update settings of process PID"
|
||||
msgstr "Einstellungen der Prozess-PID updaten"
|
||||
|
||||
#: src/main/help.c:386 src/main/help.c:401
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:387
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "Prozess-ID in FILE speichern"
|
||||
|
||||
#: src/main/help.c:390
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "die vom Prozess PID geöffnete Datei FD beobachten"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "show this help and exit"
|
||||
msgstr "zeige diese Hilfe und beende"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "show version information and exit"
|
||||
msgstr "zeige Versionsinformationen und beende"
|
||||
|
||||
#: src/main/help.c:402
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#. @-formatconst@
|
||||
#.
|
||||
#. * splint note: unavoidable use of %s in translated string. Should
|
||||
#. * be hard to exploit - the message catalogue would have to be
|
||||
#. * replaced or forced to load from another location.
|
||||
#.
|
||||
#: src/main/help.c:427
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Syntax: %s [OPTION] [DATEI]..."
|
||||
|
||||
#. @-mustfreefresh@
|
||||
#.
|
||||
#. * splint note: the gettext calls made by _() cause memory leak
|
||||
#. * warnings, but in this case it's unavoidable, and mitigated by the
|
||||
#. * fact we only translate each string once.
|
||||
#.
|
||||
#: src/main/help.c:438
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Verbindet DATEI(en) oder den Standard-Eingabe-Kanal mit dem Standard-Ausgabe-"
|
||||
"Kanal und misst den Datenstrom."
|
||||
|
||||
#: src/main/help.c:575
|
||||
#, c-format
|
||||
msgid "Please report any bugs to %s."
|
||||
msgstr "Bitte senden Sie Fehlerberichte an %s."
|
||||
|
||||
#: src/main/main.c:75
|
||||
msgid "state allocation failed"
|
||||
msgstr "Zustandszuweisung fehlgeschlagen"
|
||||
|
||||
#: src/main/main.c:243
|
||||
msgid "failed to read terminal attributes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:111
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "`option' konnte nicht allokiert werden"
|
||||
|
||||
#: src/main/options.c:124
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "`option' (argv) konnte nicht allokiert werden"
|
||||
|
||||
#: src/main/options.c:163
|
||||
msgid "integer argument expected"
|
||||
msgstr "Ganzzahliges Argument erwartet"
|
||||
|
||||
#: src/main/options.c:171
|
||||
msgid "numeric argument expected"
|
||||
msgstr "numerisches Argument erwartet"
|
||||
|
||||
#: src/main/options.c:180
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "Prozess-ID oder PID:FD-Paar erwartet"
|
||||
|
||||
#: src/main/options.c:185
|
||||
msgid "invalid process ID"
|
||||
msgstr "ungültige Prozess-ID"
|
||||
|
||||
#: src/main/options.c:358
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "`%s --help' zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:360
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "`%s -h' zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:374
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"Beim Anzeigen von Dateideskriptoren können keine Optionen für den "
|
||||
"Zeilenmodus oder den Übertragungsmodifikator verwendet werden"
|
||||
|
||||
#: src/main/options.c:381
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Anzeigen von Dateideskriptoren können keine Zeilenmodus- oder "
|
||||
"Übertragungsmodifikatoroptionen verwendet werden."
|
||||
|
||||
#: src/main/options.c:388
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"kann keine Fernbedienung verwenden, wenn Dateideskriptoren angezeigt werden"
|
||||
|
||||
#: src/main/options.c:395
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"Dateien können beim Betrachten von Dateideskriptoren nicht übertragen werden"
|
||||
|
||||
#: src/main/options.c:402
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "Nicht verfügbar auf Systemen ohne /proc/self/fdinfo"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Debugging is enabled; export the DEBUG environment variable to define "
|
||||
#~ "the\n"
|
||||
#~ "output filename.\n"
|
||||
#~ msgstr ""
|
||||
#~ "Das Debuggen ist aktiviert. Exportieren Sie die Umgebungsvariable DEBUG,\n"
|
||||
#~ "um den Ausgabedateinamen zu definieren.\n"
|
||||
|
||||
#~ msgid "%s %s - Copyright %s %s"
|
||||
#~ msgstr "%s %s - Copyright(C) %s %s"
|
||||
|
||||
#~ msgid "Web site: %s"
|
||||
#~ msgstr "Web-Site: %s"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This program is free software, and is being distributed under the\n"
|
||||
#~ "terms of the Artistic License 2.0."
|
||||
#~ msgstr ""
|
||||
#~ "Dieses Programm ist freie Software und wird unter den Bedingungen\n"
|
||||
#~ "der Artistic License verbreitet."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This program is distributed in the hope that it will be useful,\n"
|
||||
#~ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
#~ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
#~ msgstr ""
|
||||
#~ "Dieses Programm wird in der Hoffnung verbreitet, dass es nützlich sein "
|
||||
#~ "wird,\n"
|
||||
#~ "aber OHNE JEGLICHE GARANTIE; ohne die implizite Garantie von\n"
|
||||
#~ "MARKTGÄNGIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK."
|
||||
-510
@@ -1,510 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-07-30 19:07+0100\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
"From: Andrew Wood <ivarch@ubik>\n"
|
||||
"Xgettext-Options: --default-domain=pkgbuild --directory=./.pkgdir --add-"
|
||||
"comments --keyword=_ --keyword=N_\n"
|
||||
"Files: src/getopt/getopt.c src/getopt/getopt1.c src/version.c src/main/init."
|
||||
"c src/main/help.c src/main/xpmptr.c src/guts/load.c src/guts/stop.c src/guts/"
|
||||
"configure.c src/guts/make.c src/guts/install.c src/guts/prefs.c src/ui/"
|
||||
"generate.c src/ui/main.c src/ui/xpm.c src/ui/status.c src/ui/activate.c src/"
|
||||
"ui/handlers/main.c src/ui/handlers/package.c src/ui/handlers/prefs.c src/ui/"
|
||||
"handlers/dirsel.c src/ui/handlers/popup.c src/ui/handlers/help.c src/ui/"
|
||||
"textout.c src/ui/report.c src/ui/callback.c src/nls/intl/bindtextdom.c src/"
|
||||
"nls/intl/dcgettext.c src/nls/intl/dgettext.c src/nls/intl/finddomain.c src/"
|
||||
"nls/intl/gettext.c src/nls/intl/loadmsgcat.c src/nls/intl/localealias.c src/"
|
||||
"nls/intl/textdomain.c src/nls/intl-cat/cat-compat.c src/nls/intl-gett/intl-"
|
||||
"compat.c\n"
|
||||
|
||||
#: src/pv/cursor.c:85
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "échec de lecture du nom du terminal"
|
||||
|
||||
#: src/pv/cursor.c:117
|
||||
msgid "failed to open lock file"
|
||||
msgstr "échec de l'ouverture du fichier de verrouillage"
|
||||
|
||||
#: src/pv/cursor.c:150
|
||||
msgid "lock attempt failed"
|
||||
msgstr "tentative de verrouillage échoué"
|
||||
|
||||
#: src/pv/cursor.c:391
|
||||
msgid "failed to open terminal"
|
||||
msgstr "l'ouverture du terminal a échoué"
|
||||
|
||||
#: src/pv/file.c:119
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "ne peut pas passer au début de la sortie"
|
||||
|
||||
#: src/pv/file.c:210
|
||||
msgid "failed to close file"
|
||||
msgstr "la fermeture du fichier a échoué"
|
||||
|
||||
#: src/pv/file.c:232
|
||||
msgid "failed to read file"
|
||||
msgstr "la lecture du fichier a échoué"
|
||||
|
||||
#: src/pv/file.c:239 src/main/options.c:284
|
||||
msgid "failed to stat file"
|
||||
msgstr "échec à statuer sur le fichier"
|
||||
|
||||
#: src/pv/file.c:246
|
||||
msgid "failed to stat output file"
|
||||
msgstr "échec à statuer sur le fichier de sortie"
|
||||
|
||||
#: src/pv/file.c:268
|
||||
msgid "input file is output file"
|
||||
msgstr "fichiers d'entré et de sortie sont les mêmes"
|
||||
|
||||
#: src/pv/transfer.c:359
|
||||
msgid "read failed"
|
||||
msgstr "la lecture a échoué"
|
||||
|
||||
#: src/pv/transfer.c:374
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "avertissement: erreurs de lecture détectées"
|
||||
|
||||
#: src/pv/transfer.c:386
|
||||
msgid "file is not seekable"
|
||||
msgstr "ne peut pas se déplacer dans le fichier"
|
||||
|
||||
#: src/pv/transfer.c:445
|
||||
msgid "failed to seek past error"
|
||||
msgstr "n'a pas réussi à dépasser l'erreur"
|
||||
|
||||
#: src/pv/transfer.c:461
|
||||
msgid "skipped past read error"
|
||||
msgstr "erreur de lecture dépassée"
|
||||
|
||||
#: src/pv/transfer.c:461 src/pv/display.c:660
|
||||
msgid "B"
|
||||
msgstr "O"
|
||||
|
||||
#: src/pv/transfer.c:617
|
||||
msgid "write failed"
|
||||
msgstr "l'écriture a échoué"
|
||||
|
||||
#: src/pv/transfer.c:736 src/pv/display.c:594
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "l'allocation de mémoire tampon a échoué"
|
||||
|
||||
#.
|
||||
#. * Any other error is a problem and we must report back.
|
||||
#.
|
||||
#: src/pv/transfer.c:833
|
||||
msgid "select call failed"
|
||||
msgstr "appel de sélection a échoué"
|
||||
|
||||
#: src/pv/watchpid.c:73 src/pv/watchpid.c:83 src/pv/watchpid.c:94
|
||||
#: src/pv/watchpid.c:102 src/pv/watchpid.c:139 src/pv/watchpid.c:150
|
||||
#: src/pv/watchpid.c:158 src/pv/watchpid.c:169 src/pv/watchpid.c:253
|
||||
#: src/pv/watchpid.c:261 src/pv/watchpid.c:292 src/pv/watchpid.c:312
|
||||
#: src/pv/loop.c:506 src/pv/loop.c:558 src/pv/loop.c:602
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:95 src/pv/watchpid.c:104
|
||||
#: src/pv/watchpid.c:150 src/pv/watchpid.c:159 src/pv/watchpid.c:171
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:104 src/pv/watchpid.c:171
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "pas un fichier ordinaire ou un périphérique de bloc"
|
||||
|
||||
#: src/pv/state.c:30
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:59
|
||||
msgid "none"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:159
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:164
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:656
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:711 src/pv/display.c:722
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "B/s"
|
||||
msgstr "O/s"
|
||||
|
||||
#: src/pv/display.c:762 src/pv/display.c:766 src/pv/display.c:825
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#. GNU standard license line and free software notice
|
||||
#: src/main/version.c:28
|
||||
msgid "License: Artistic v2.0 <https://opensource.org/license/artistic-2-0/>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#. Project web site link
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:215
|
||||
msgid "message not received"
|
||||
msgstr "message non reçu"
|
||||
|
||||
#: src/main/remote.c:318
|
||||
msgid "IPC not supported on this system"
|
||||
msgstr "IPC non pris en charge sur ce système"
|
||||
|
||||
#: src/main/help.c:283
|
||||
msgid "show progress bar"
|
||||
msgstr "affiche la barre de progression"
|
||||
|
||||
#: src/main/help.c:286
|
||||
msgid "show elapsed time"
|
||||
msgstr "affiche le temps écoulé"
|
||||
|
||||
#: src/main/help.c:289
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "affiche l'heure approximative de l'achèvement de la tâche"
|
||||
|
||||
#: src/main/help.c:292
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "affiche l'heure absolute de l'achèvement de la tâche"
|
||||
|
||||
#: src/main/help.c:295
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "affiche le taux de tranfert des données"
|
||||
|
||||
#: src/main/help.c:298
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "afficher le compteur de taux moyen de transfert de données"
|
||||
|
||||
#: src/main/help.c:300 src/main/help.c:328 src/main/help.c:340
|
||||
msgid "SEC"
|
||||
msgstr "SEC"
|
||||
|
||||
#: src/main/help.c:301
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:304
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "affiche le nombre d'octets transférés"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "afficher le pourcentage de tampon de transfert utilisé"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:313
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "affiche NUM octets pour la dernière fois écrits"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:316
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "définir le format de sortie sur FORMAT"
|
||||
|
||||
#: src/main/help.c:319
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "imprime en pourcentage, pas les informations visuelles"
|
||||
|
||||
#: src/main/help.c:322
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "n'afficher aucune information de transfert"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "ne rien afficher avant qu'au moins un octet soit tranféré"
|
||||
|
||||
#: src/main/help.c:329
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "n'afficher rien jusqu'à ce que SEC secondes se soient écoulées"
|
||||
|
||||
#: src/main/help.c:331
|
||||
msgid "SIZE"
|
||||
msgstr "TAILLE"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "ajuste la taille estimée des données à TAILLE octets"
|
||||
|
||||
#: src/main/help.c:335
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "compte les lignes au lieu des octets"
|
||||
|
||||
#: src/main/help.c:338
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "les lignes sont terminées par un nul"
|
||||
|
||||
#: src/main/help.c:341
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "mise-à-jour toute les SEC secondes"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "WIDTH"
|
||||
msgstr "LARGEUR"
|
||||
|
||||
#: src/main/help.c:344
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "présumer la largeur du terminal à LARGEUR caractères"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "HEIGHT"
|
||||
msgstr "HAUTEUR"
|
||||
|
||||
#: src/main/help.c:347
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "présumer la hauteur du terminal à HAUTEUR lignes"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "NAME"
|
||||
msgstr "NOM"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "préfixer les informations visuelles avec NOM"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "imprime vers la sortie d'erreur même si ce n'est pas un terminal"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utiliser les séquences d'échappements de positionnement de curseur"
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "RATE"
|
||||
msgstr "TAUX"
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limite le taux de transfer à TAUX octets par seconde"
|
||||
|
||||
#: src/main/help.c:362
|
||||
msgid "BYTES"
|
||||
msgstr "OCTETS"
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "Utiliser une mémoire tampon de OCTETS octets"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "n'utilisez jamais splice(), utilisez toujours read/write"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignorer les erreurs de lecture dans l'entrée"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "arrêter après le transfert de --size octets"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:381
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "update settings of process PID"
|
||||
msgstr "mettre-à-jour la configuration du processus PID"
|
||||
|
||||
#: src/main/help.c:386 src/main/help.c:401
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:387
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "enregistrer l'ID de processus dans FILE"
|
||||
|
||||
#: src/main/help.c:390
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "regarder le fichier FD ouvert par le processus PID"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "show this help and exit"
|
||||
msgstr "afficher cette aide puis quitter"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "show version information and exit"
|
||||
msgstr "afficher la version puis quitter"
|
||||
|
||||
#: src/main/help.c:402
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#. @-formatconst@
|
||||
#.
|
||||
#. * splint note: unavoidable use of %s in translated string. Should
|
||||
#. * be hard to exploit - the message catalogue would have to be
|
||||
#. * replaced or forced to load from another location.
|
||||
#.
|
||||
#: src/main/help.c:427
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Utilisation : %s [OPTIONS] [FICHIER]..."
|
||||
|
||||
#. @-mustfreefresh@
|
||||
#.
|
||||
#. * splint note: the gettext calls made by _() cause memory leak
|
||||
#. * warnings, but in this case it's unavoidable, and mitigated by the
|
||||
#. * fact we only translate each string once.
|
||||
#.
|
||||
#: src/main/help.c:438
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Concatène FICHIER(s), ou l'entrée standard, sur la sortie standard avec "
|
||||
"monitorage."
|
||||
|
||||
#: src/main/help.c:575
|
||||
#, c-format
|
||||
msgid "Please report any bugs to %s."
|
||||
msgstr "SVP rapporter touts bogues à %s."
|
||||
|
||||
#: src/main/main.c:75
|
||||
msgid "state allocation failed"
|
||||
msgstr "échec de l'allocation de mémoire de condition"
|
||||
|
||||
#: src/main/main.c:243
|
||||
msgid "failed to read terminal attributes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:111
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "l'allocation pour la structure d'une option a echoué"
|
||||
|
||||
#: src/main/options.c:124
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "l'allocation pour la structure de l'option argv a echoué"
|
||||
|
||||
#: src/main/options.c:163
|
||||
msgid "integer argument expected"
|
||||
msgstr "Valeur entière attendue"
|
||||
|
||||
#: src/main/options.c:171
|
||||
msgid "numeric argument expected"
|
||||
msgstr "Valeur numérique attendue"
|
||||
|
||||
#: src/main/options.c:180
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID de processus ou paire pid:fd attendue"
|
||||
|
||||
#: src/main/options.c:185
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processus non valide"
|
||||
|
||||
#: src/main/options.c:358
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Essayez `%s --help' pour plus d'information."
|
||||
|
||||
#: src/main/options.c:360
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Essayez `%s -h' pour plus d'information."
|
||||
|
||||
#: src/main/options.c:374
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser le mode ligne ou les options de modificateur de "
|
||||
"transfert lors de la visualisation des descripteurs de fichiers"
|
||||
|
||||
#: src/main/options.c:381
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser le positionnement du curseur lors de la visualisation "
|
||||
"des descripteurs de fichier"
|
||||
|
||||
#: src/main/options.c:388
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser la télécommande lors de la visualisation des "
|
||||
"descripteurs de fichiers"
|
||||
|
||||
#: src/main/options.c:395
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible de transférer des fichiers lorsque vous regardez des descripteurs "
|
||||
"de fichiers"
|
||||
|
||||
#: src/main/options.c:402
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "non disponible sur les systèmes sans /proc/self/fdinfo"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Debugging is enabled; export the DEBUG environment variable to define "
|
||||
#~ "the\n"
|
||||
#~ "output filename.\n"
|
||||
#~ msgstr ""
|
||||
#~ "Le débogage est activé; exportez la variable d'environnement DEBUG pour\n"
|
||||
#~ "définir le nom du fichier de sortie.\n"
|
||||
|
||||
#~ msgid "%s %s - Copyright %s %s"
|
||||
#~ msgstr "%s %s - Copyright(C) %s %s"
|
||||
|
||||
#~ msgid "Web site: %s"
|
||||
#~ msgstr "Site Web: %s"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This program is free software, and is being distributed under the\n"
|
||||
#~ "terms of the Artistic License 2.0."
|
||||
#~ msgstr ""
|
||||
#~ "Ce programme est un logiciel libre et est distribué sous les termes\n"
|
||||
#~ "anglophone de la Licence Artistique 2.0 (Artistic License 2.0)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This program is distributed in the hope that it will be useful,\n"
|
||||
#~ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
#~ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
#~ msgstr ""
|
||||
#~ "Ce programme est distribué dans l'espoir qu'il sera utile, mais\n"
|
||||
#~ "SANS GARANTIE AUCUNE; ni même de garantie sous-entendu que le\n"
|
||||
#~ "programme soit COMMERCIALISABLE ou APPLICABLE À UNE TÂCHE\n"
|
||||
#~ "PARTICULIÈRE."
|
||||
-472
@@ -1,472 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-07-30 19:07+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/pv/cursor.c:85
|
||||
msgid "failed to get terminal name"
|
||||
msgstr ""
|
||||
|
||||
# "Przewidywany czas ukończenia" for ETA is too long
|
||||
#: src/pv/cursor.c:117
|
||||
msgid "failed to open lock file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:150
|
||||
msgid "lock attempt failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:391
|
||||
msgid "failed to open terminal"
|
||||
msgstr "nie udało się otworzyć terminala"
|
||||
|
||||
#: src/pv/file.c:119
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr ""
|
||||
|
||||
# "Przewidywany czas ukończenia" for ETA is too long
|
||||
#: src/pv/file.c:210
|
||||
msgid "failed to close file"
|
||||
msgstr "nie udało się zamknąć pliku"
|
||||
|
||||
#: src/pv/file.c:232
|
||||
msgid "failed to read file"
|
||||
msgstr "nie udało się odczytać pliku"
|
||||
|
||||
#: src/pv/file.c:239 src/main/options.c:284
|
||||
msgid "failed to stat file"
|
||||
msgstr "nie udało się wykonać operacji stat na pliku"
|
||||
|
||||
#: src/pv/file.c:246
|
||||
msgid "failed to stat output file"
|
||||
msgstr "nie udało się wykonać operacji stat na pliku wyjściowym"
|
||||
|
||||
#: src/pv/file.c:268
|
||||
msgid "input file is output file"
|
||||
msgstr "plik wejściowy jest zarazem plikiem wyjściowym"
|
||||
|
||||
#: src/pv/transfer.c:359
|
||||
msgid "read failed"
|
||||
msgstr "błąd odczytu"
|
||||
|
||||
#: src/pv/transfer.c:374
|
||||
msgid "warning: read errors detected"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:386
|
||||
msgid "file is not seekable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:445
|
||||
msgid "failed to seek past error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:461
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:461 src/pv/display.c:660
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/transfer.c:617
|
||||
msgid "write failed"
|
||||
msgstr "błąd zapisu"
|
||||
|
||||
#: src/pv/transfer.c:736 src/pv/display.c:594
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "nie udało się zaalokować bufora"
|
||||
|
||||
#.
|
||||
#. * Any other error is a problem and we must report back.
|
||||
#.
|
||||
#: src/pv/transfer.c:833
|
||||
msgid "select call failed"
|
||||
msgstr "nie udało się wywołać funkcji select"
|
||||
|
||||
#: src/pv/watchpid.c:73 src/pv/watchpid.c:83 src/pv/watchpid.c:94
|
||||
#: src/pv/watchpid.c:102 src/pv/watchpid.c:139 src/pv/watchpid.c:150
|
||||
#: src/pv/watchpid.c:158 src/pv/watchpid.c:169 src/pv/watchpid.c:253
|
||||
#: src/pv/watchpid.c:261 src/pv/watchpid.c:292 src/pv/watchpid.c:312
|
||||
#: src/pv/loop.c:506 src/pv/loop.c:558 src/pv/loop.c:602
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:95 src/pv/watchpid.c:104
|
||||
#: src/pv/watchpid.c:150 src/pv/watchpid.c:159 src/pv/watchpid.c:171
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:104 src/pv/watchpid.c:171
|
||||
msgid "not a regular file or block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:30
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:59
|
||||
msgid "none"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:159
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:164
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:656
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:711 src/pv/display.c:722
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:762 src/pv/display.c:766 src/pv/display.c:825
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#. GNU standard license line and free software notice
|
||||
#: src/main/version.c:28
|
||||
msgid "License: Artistic v2.0 <https://opensource.org/license/artistic-2-0/>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#. Project web site link
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:215
|
||||
msgid "message not received"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:318
|
||||
msgid "IPC not supported on this system"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:283
|
||||
msgid "show progress bar"
|
||||
msgstr "pokaż pasek postępu"
|
||||
|
||||
#: src/main/help.c:286
|
||||
msgid "show elapsed time"
|
||||
msgstr "pokaż upływający czas"
|
||||
|
||||
#: src/main/help.c:289
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "pokaż szacowany czas ukończenia"
|
||||
|
||||
#: src/main/help.c:292
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:295
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "pokaż licznik prędkości przesyłania"
|
||||
|
||||
#: src/main/help.c:298
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:300 src/main/help.c:328 src/main/help.c:340
|
||||
msgid "SEC"
|
||||
msgstr "WARTOŚĆ"
|
||||
|
||||
#: src/main/help.c:301
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:304
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "pokaż ilość przesłanych bajtów"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:313
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:316
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:319
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "wświetl wyjście procentowo, bez graficznej prezentacji"
|
||||
|
||||
#: src/main/help.c:322
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "nie wyświetlaj żadnych informacji o przesyłaniu"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "nie wyświetlaj nic aż do pierwszego przesłanego bajtu"
|
||||
|
||||
#: src/main/help.c:329
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:331
|
||||
msgid "SIZE"
|
||||
msgstr "WARTOŚĆ"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "ustaw oczekiwany rozmiar danych na WARTOŚĆ bajtów"
|
||||
|
||||
#: src/main/help.c:335
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:338
|
||||
msgid "lines are null-terminated"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:341
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualizuj co każde WARTOŚĆ sekund"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "WIDTH"
|
||||
msgstr "WARTOŚĆ"
|
||||
|
||||
#: src/main/help.c:344
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:347
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "NAME"
|
||||
msgstr "NAZWA"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "poprzedź informacje prefiksem NAZWA"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "pokaż wyjście nawet gdy błędy nie są typu terminal"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "używaj sekwencji escape do pozycjonowania"
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "ogranicz przesyłane dane do RATE bajtów na sekundę"
|
||||
|
||||
#: src/main/help.c:362
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "skip read errors in input"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:381
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "update settings of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:386 src/main/help.c:401
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:387
|
||||
msgid "save process ID in FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:390
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "show this help and exit"
|
||||
msgstr "wyświetl te informacje z pomocą i wyjdź"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "show version information and exit"
|
||||
msgstr "wyświetl informacje o wersji i wyjdź"
|
||||
|
||||
#: src/main/help.c:402
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#. @-formatconst@
|
||||
#.
|
||||
#. * splint note: unavoidable use of %s in translated string. Should
|
||||
#. * be hard to exploit - the message catalogue would have to be
|
||||
#. * replaced or forced to load from another location.
|
||||
#.
|
||||
#: src/main/help.c:427
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Sposób użycia: %s [OPCJA] [PLIK]..."
|
||||
|
||||
#. @-mustfreefresh@
|
||||
#.
|
||||
#. * splint note: the gettext calls made by _() cause memory leak
|
||||
#. * warnings, but in this case it's unavoidable, and mitigated by the
|
||||
#. * fact we only translate each string once.
|
||||
#.
|
||||
#: src/main/help.c:438
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Łączenie PLIK(ów) lub wejścia standardowego, do wyjścia standardowego z "
|
||||
"monitoringiem."
|
||||
|
||||
#: src/main/help.c:575
|
||||
#, c-format
|
||||
msgid "Please report any bugs to %s."
|
||||
msgstr "Proszę przesyłać zgłoszenia błędów do %s."
|
||||
|
||||
#: src/main/main.c:75
|
||||
msgid "state allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:243
|
||||
msgid "failed to read terminal attributes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:111
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji"
|
||||
|
||||
#: src/main/options.c:124
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji argv"
|
||||
|
||||
#: src/main/options.c:163
|
||||
msgid "integer argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:171
|
||||
msgid "numeric argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:180
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:185
|
||||
msgid "invalid process ID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:358
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Spróbuj `%s --help' by uzyskać więcej informacji"
|
||||
|
||||
#: src/main/options.c:360
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Spróbuj `%s -h' by uzyskać więcej informacji"
|
||||
|
||||
#: src/main/options.c:374
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:381
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:388
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:395
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:402
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Web site: %s"
|
||||
#~ msgstr "Strona WWW: %s"
|
||||
-501
@@ -1,501 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-07-30 19:07+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/pv/cursor.c:85
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "erro ao ler o nome do terminal"
|
||||
|
||||
#: src/pv/cursor.c:117
|
||||
msgid "failed to open lock file"
|
||||
msgstr "erro ao abrir arquivo de bloqueio"
|
||||
|
||||
#: src/pv/cursor.c:150
|
||||
msgid "lock attempt failed"
|
||||
msgstr "tentativa de bloqueio falhou"
|
||||
|
||||
#: src/pv/cursor.c:391
|
||||
msgid "failed to open terminal"
|
||||
msgstr "erro abrindo o terminal"
|
||||
|
||||
#: src/pv/file.c:119
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "não pode mover para o início da produção"
|
||||
|
||||
#: src/pv/file.c:210
|
||||
msgid "failed to close file"
|
||||
msgstr "erro fechando o arquivo"
|
||||
|
||||
#: src/pv/file.c:232
|
||||
msgid "failed to read file"
|
||||
msgstr "erro lendo o arquivo"
|
||||
|
||||
#: src/pv/file.c:239 src/main/options.c:284
|
||||
msgid "failed to stat file"
|
||||
msgstr "erro obtendo informações do arquivo"
|
||||
|
||||
#: src/pv/file.c:246
|
||||
msgid "failed to stat output file"
|
||||
msgstr "erro obtendo informações do arquivo de saída"
|
||||
|
||||
#: src/pv/file.c:268
|
||||
msgid "input file is output file"
|
||||
msgstr "os arquivos de entrada e saída são o mesmo"
|
||||
|
||||
#: src/pv/transfer.c:359
|
||||
msgid "read failed"
|
||||
msgstr "erro de leitura"
|
||||
|
||||
#: src/pv/transfer.c:374
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "aviso: erros de leitura detectados"
|
||||
|
||||
#: src/pv/transfer.c:386
|
||||
msgid "file is not seekable"
|
||||
msgstr "não pode mover dentro do arquivo"
|
||||
|
||||
#: src/pv/transfer.c:445
|
||||
msgid "failed to seek past error"
|
||||
msgstr "não pode ir além do erro"
|
||||
|
||||
#: src/pv/transfer.c:461
|
||||
msgid "skipped past read error"
|
||||
msgstr "ignorado erro de leitura"
|
||||
|
||||
#: src/pv/transfer.c:461 src/pv/display.c:660
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:617
|
||||
msgid "write failed"
|
||||
msgstr "erro de gravação"
|
||||
|
||||
#: src/pv/transfer.c:736 src/pv/display.c:594
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "erro alocando o buffer"
|
||||
|
||||
#.
|
||||
#. * Any other error is a problem and we must report back.
|
||||
#.
|
||||
#: src/pv/transfer.c:833
|
||||
msgid "select call failed"
|
||||
msgstr "erro na chamada da função select"
|
||||
|
||||
#: src/pv/watchpid.c:73 src/pv/watchpid.c:83 src/pv/watchpid.c:94
|
||||
#: src/pv/watchpid.c:102 src/pv/watchpid.c:139 src/pv/watchpid.c:150
|
||||
#: src/pv/watchpid.c:158 src/pv/watchpid.c:169 src/pv/watchpid.c:253
|
||||
#: src/pv/watchpid.c:261 src/pv/watchpid.c:292 src/pv/watchpid.c:312
|
||||
#: src/pv/loop.c:506 src/pv/loop.c:558 src/pv/loop.c:602
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:95 src/pv/watchpid.c:104
|
||||
#: src/pv/watchpid.c:150 src/pv/watchpid.c:159 src/pv/watchpid.c:171
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:104 src/pv/watchpid.c:171
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "não é um arquivo regular ou dispositivo de bloqueio"
|
||||
|
||||
#: src/pv/state.c:30
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:59
|
||||
msgid "none"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:159
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:164
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:656
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:711 src/pv/display.c:722
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:762 src/pv/display.c:766 src/pv/display.c:825
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#. GNU standard license line and free software notice
|
||||
#: src/main/version.c:28
|
||||
msgid "License: Artistic v2.0 <https://opensource.org/license/artistic-2-0/>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#. Project web site link
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:215
|
||||
msgid "message not received"
|
||||
msgstr "mensagem não recebida"
|
||||
|
||||
#: src/main/remote.c:318
|
||||
msgid "IPC not supported on this system"
|
||||
msgstr "IPC não suportado neste sistema"
|
||||
|
||||
#: src/main/help.c:283
|
||||
msgid "show progress bar"
|
||||
msgstr "exibe barra de progressão"
|
||||
|
||||
#: src/main/help.c:286
|
||||
msgid "show elapsed time"
|
||||
msgstr "exibe tempo passado"
|
||||
|
||||
#: src/main/help.c:289
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "exibe o tempo estimado de término"
|
||||
|
||||
#: src/main/help.c:292
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "exibe o tempo absoluto estimado de término"
|
||||
|
||||
#: src/main/help.c:295
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "exibe a taxa de transferência"
|
||||
|
||||
#: src/main/help.c:298
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "exibe o contador da taxa média de transferência de dados"
|
||||
|
||||
#: src/main/help.c:300 src/main/help.c:328 src/main/help.c:340
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:301
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:304
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "exibe a quantidade de bytes transferidos"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "exibe a porcentagem de buffer de transferência em uso"
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:313
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "exibe NUM bytes gravados pela última vez"
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:316
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "definir o formato de saída para FORMAT"
|
||||
|
||||
#: src/main/help.c:319
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "exibe apenas as porcentagens, sem informações visuais"
|
||||
|
||||
#: src/main/help.c:322
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "executa programa sem exibir quaisquer informações"
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "não exibe nada até iniciar o processamento"
|
||||
|
||||
#: src/main/help.c:329
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "não exibir nada até que os segundos SEC tenham passado"
|
||||
|
||||
#: src/main/help.c:331
|
||||
msgid "SIZE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "seta a quantidade estimada de dados em SIZE bytes"
|
||||
|
||||
#: src/main/help.c:335
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "contar linhas em vez de bytes"
|
||||
|
||||
#: src/main/help.c:338
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "linhas são terminadas em nulo"
|
||||
|
||||
#: src/main/help.c:341
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "atualiza informações a cada SEC segundos"
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:344
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "presuma que o terminal tem WIDTH caracteres de largura"
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:347
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "presuma que o terminal tem HEIGHT caracteres de altura"
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "exibe NAME antes das demais informações"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "gera dados mesmo que a saída de erro seja redirecionada"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utiliza caracteres de escape para posicionar o cursor"
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limita a transferência a RATE bytes por segundo"
|
||||
|
||||
#: src/main/help.c:362
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "use um tamanho de buffer de BYTES"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nunca use splice(), sempre use read/write"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignorar erros de leitura em entrada"
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "parar após --size bytes terem sido transferidos"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:381
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "update settings of process PID"
|
||||
msgstr "atualizar as configurações do processo PID"
|
||||
|
||||
#: src/main/help.c:386 src/main/help.c:401
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:387
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "salvar ID do processo em FILE"
|
||||
|
||||
#: src/main/help.c:390
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "assistir arquivo FD aberto pelo processo PID"
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "show this help and exit"
|
||||
msgstr "exibe esta tela de ajuda e termina"
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "show version information and exit"
|
||||
msgstr "exibe a versão e termina"
|
||||
|
||||
#: src/main/help.c:402
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#. @-formatconst@
|
||||
#.
|
||||
#. * splint note: unavoidable use of %s in translated string. Should
|
||||
#. * be hard to exploit - the message catalogue would have to be
|
||||
#. * replaced or forced to load from another location.
|
||||
#.
|
||||
#: src/main/help.c:427
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Uso: %s [OPÇÕES] [ARQUIVOS]..."
|
||||
|
||||
#. @-mustfreefresh@
|
||||
#.
|
||||
#. * splint note: the gettext calls made by _() cause memory leak
|
||||
#. * warnings, but in this case it's unavoidable, and mitigated by the
|
||||
#. * fact we only translate each string once.
|
||||
#.
|
||||
#: src/main/help.c:438
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Concatena ARQUIVO(s) ou a entrada padrão e grava na saída padrão, com "
|
||||
"monitoramento."
|
||||
|
||||
#: src/main/help.c:575
|
||||
#, c-format
|
||||
msgid "Please report any bugs to %s."
|
||||
msgstr "Por favor, reporte quaisquer defeitos para %s."
|
||||
|
||||
#: src/main/main.c:75
|
||||
msgid "state allocation failed"
|
||||
msgstr "alocação de memória de status falhou"
|
||||
|
||||
#: src/main/main.c:243
|
||||
msgid "failed to read terminal attributes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:111
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções"
|
||||
|
||||
#: src/main/options.c:124
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções argv"
|
||||
|
||||
#: src/main/options.c:163
|
||||
msgid "integer argument expected"
|
||||
msgstr "argumento inteiro esperado"
|
||||
|
||||
#: src/main/options.c:171
|
||||
msgid "numeric argument expected"
|
||||
msgstr "argumento numérico esperado"
|
||||
|
||||
#: src/main/options.c:180
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID do processo ou par pid:fd esperado"
|
||||
|
||||
#: src/main/options.c:185
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processo inválido"
|
||||
|
||||
#: src/main/options.c:358
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Tente `%s --help' para maiores informações."
|
||||
|
||||
#: src/main/options.c:360
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Tente `%s -h' para maiores informações."
|
||||
|
||||
#: src/main/options.c:374
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"não pode usar o modo de linha ou opções de modificador de transferência ao "
|
||||
"assistir os descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:381
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"não pode usar o posicionamento do cursor ao observar os descritores de "
|
||||
"arquivo"
|
||||
|
||||
#: src/main/options.c:388
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "não pode usar o controle remoto ao assistir os descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:395
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "não pode transferir arquivos ao assistir descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:402
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "não disponível em sistemas sem /proc/self/fdinfo"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Debugging is enabled; export the DEBUG environment variable to define "
|
||||
#~ "the\n"
|
||||
#~ "output filename.\n"
|
||||
#~ msgstr ""
|
||||
#~ "A depuração está habilitada; exporte a variável de ambiente DEBUG para\n"
|
||||
#~ "definir o nome do arquivo de saída.\n"
|
||||
|
||||
#~ msgid "%s %s - Copyright %s %s"
|
||||
#~ msgstr "%s %s - Copyright(C) %s %s"
|
||||
|
||||
#~ msgid "Web site: %s"
|
||||
#~ msgstr "Site: %s"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This program is free software, and is being distributed under the\n"
|
||||
#~ "terms of the Artistic License 2.0."
|
||||
#~ msgstr ""
|
||||
#~ "Este programa é um software livre, distribuído sob os termos da\n"
|
||||
#~ "Licença Artística."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This program is distributed in the hope that it will be useful,\n"
|
||||
#~ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
#~ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
#~ msgstr ""
|
||||
#~ "Este programa é distribuído com o intuito de que seja útil,\n"
|
||||
#~ "porém SEM QUAISQUER GARANTIAS; sem inclusive as garantias implícitas de\n"
|
||||
#~ "COMERCIALIZAÇÃO e ADEQUAÇÃO A OBJETIVOS PARTICULARES."
|
||||
-467
@@ -1,467 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-07-30 19:07+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/pv/cursor.c:85
|
||||
msgid "failed to get terminal name"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:117
|
||||
msgid "failed to open lock file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:150
|
||||
msgid "lock attempt failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:391
|
||||
msgid "failed to open terminal"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:119
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:210
|
||||
msgid "failed to close file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:232
|
||||
msgid "failed to read file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:239 src/main/options.c:284
|
||||
msgid "failed to stat file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:246
|
||||
msgid "failed to stat output file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:268
|
||||
msgid "input file is output file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:359
|
||||
msgid "read failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:374
|
||||
msgid "warning: read errors detected"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:386
|
||||
msgid "file is not seekable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:445
|
||||
msgid "failed to seek past error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:461
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:461 src/pv/display.c:660
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:617
|
||||
msgid "write failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:736 src/pv/display.c:594
|
||||
msgid "buffer allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#.
|
||||
#. * Any other error is a problem and we must report back.
|
||||
#.
|
||||
#: src/pv/transfer.c:833
|
||||
msgid "select call failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:73 src/pv/watchpid.c:83 src/pv/watchpid.c:94
|
||||
#: src/pv/watchpid.c:102 src/pv/watchpid.c:139 src/pv/watchpid.c:150
|
||||
#: src/pv/watchpid.c:158 src/pv/watchpid.c:169 src/pv/watchpid.c:253
|
||||
#: src/pv/watchpid.c:261 src/pv/watchpid.c:292 src/pv/watchpid.c:312
|
||||
#: src/pv/loop.c:506 src/pv/loop.c:558 src/pv/loop.c:602
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:95 src/pv/watchpid.c:104
|
||||
#: src/pv/watchpid.c:150 src/pv/watchpid.c:159 src/pv/watchpid.c:171
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:104 src/pv/watchpid.c:171
|
||||
msgid "not a regular file or block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:30
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:59
|
||||
msgid "none"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:159
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:164
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:656
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:711 src/pv/display.c:722
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:714 src/pv/display.c:726
|
||||
msgid "B/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:762 src/pv/display.c:766 src/pv/display.c:825
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#. GNU standard license line and free software notice
|
||||
#: src/main/version.c:28
|
||||
msgid "License: Artistic v2.0 <https://opensource.org/license/artistic-2-0/>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#. Project web site link
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:215
|
||||
msgid "message not received"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:318
|
||||
msgid "IPC not supported on this system"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:283
|
||||
msgid "show progress bar"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:286
|
||||
msgid "show elapsed time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:289
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:292
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:295
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:298
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:300 src/main/help.c:328 src/main/help.c:340
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:301
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:304
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:312
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:313
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:315
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:316
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:319
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:322
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:326
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:329
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:331
|
||||
msgid "SIZE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:335
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:338
|
||||
msgid "lines are null-terminated"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:341
|
||||
msgid "update every SEC seconds"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:343
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:344
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:346
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:347
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:349
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:362
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "skip read errors in input"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:372
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:381
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "update settings of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:386 src/main/help.c:401
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:387
|
||||
msgid "save process ID in FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:390
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:395
|
||||
msgid "show this help and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "show version information and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:402
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#. @-formatconst@
|
||||
#.
|
||||
#. * splint note: unavoidable use of %s in translated string. Should
|
||||
#. * be hard to exploit - the message catalogue would have to be
|
||||
#. * replaced or forced to load from another location.
|
||||
#.
|
||||
#: src/main/help.c:427
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr ""
|
||||
|
||||
#. @-mustfreefresh@
|
||||
#.
|
||||
#. * splint note: the gettext calls made by _() cause memory leak
|
||||
#. * warnings, but in this case it's unavoidable, and mitigated by the
|
||||
#. * fact we only translate each string once.
|
||||
#.
|
||||
#: src/main/help.c:438
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:575
|
||||
#, c-format
|
||||
msgid "Please report any bugs to %s."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:75
|
||||
msgid "state allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:243
|
||||
msgid "failed to read terminal attributes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:111
|
||||
msgid "option structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:124
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:163
|
||||
msgid "integer argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:171
|
||||
msgid "numeric argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:180
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:185
|
||||
msgid "invalid process ID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:358
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:360
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:374
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:381
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:388
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:395
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:402
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr ""
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Functions for updating the calculated state of the transfer.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Update the current average rate, using a ring buffer of past transfer
|
||||
* positions - if this is the first entry, use the provided instantaneous
|
||||
* rate, otherwise calculate the average rate from the difference between
|
||||
* the current position + elapsed time pair, and the oldest pair in the
|
||||
* buffer. The current elapsed time and amount transferred (both from
|
||||
* "transfer") are added to the buffer.
|
||||
*/
|
||||
static void pv__update_average_rate_history(pvtransfercalc_t calc, readonly_pvtransferstate_t transfer,
|
||||
unsigned int history_interval, long double rate)
|
||||
{
|
||||
size_t first = calc->history_first;
|
||||
size_t last = calc->history_last;
|
||||
long double last_elapsed;
|
||||
|
||||
if (NULL == calc->history)
|
||||
return;
|
||||
|
||||
last_elapsed = calc->history[last].elapsed_sec;
|
||||
|
||||
/*
|
||||
* Do nothing if this is not the first call but not enough time has
|
||||
* elapsed since the previous call yet.
|
||||
*/
|
||||
if ((last_elapsed > 0.0)
|
||||
&& (transfer->elapsed_seconds < (last_elapsed + history_interval)))
|
||||
return;
|
||||
|
||||
/*
|
||||
* If this is not the first call, add a new entry to the ring
|
||||
* buffer.
|
||||
*/
|
||||
if (last_elapsed > 0.0) {
|
||||
size_t len = calc->history_len;
|
||||
last = (last + 1) % len;
|
||||
calc->history_last = last;
|
||||
if (last == first) {
|
||||
first = (first + 1) % len;
|
||||
calc->history_first = first;
|
||||
}
|
||||
}
|
||||
|
||||
calc->history[last].elapsed_sec = transfer->elapsed_seconds;
|
||||
calc->history[last].transferred = transfer->transferred;
|
||||
|
||||
if (first == last) {
|
||||
calc->current_avg_rate = rate;
|
||||
} else {
|
||||
off_t bytes = (calc->history[last].transferred - calc->history[first].transferred);
|
||||
long double sec = (calc->history[last].elapsed_sec - calc->history[first].elapsed_sec);
|
||||
/* Safety check to avoid division by zero. */
|
||||
if (sec < 0.000001 && sec > -0.000001)
|
||||
sec = 0.000001;
|
||||
calc->current_avg_rate = (long double) bytes / sec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update all calculated transfer state in calc (usually from state->calc).
|
||||
*
|
||||
* If "final" is true, this is the final update, so calc->transfer_rate and
|
||||
* calc->average_rate are given as an average over the whole transfer;
|
||||
* otherwise they are the current transfer rate and current average rate.
|
||||
*
|
||||
* The value of calc->percentage will reflect the percentage completion if
|
||||
* control->size is greater than zero, otherwise it will increase by 2 each
|
||||
* call and wrap at 200.
|
||||
*/
|
||||
void pv_calculate_transfer_rate(pvtransfercalc_t calc, readonly_pvtransferstate_t transfer,
|
||||
readonly_pvcontrol_t control, readonly_pvdisplay_t display, bool final)
|
||||
{
|
||||
off_t bytes_since_last;
|
||||
long double time_since_last, transfer_rate, average_rate;
|
||||
|
||||
/* Quick safety checks for null pointers. */
|
||||
if (NULL == calc)
|
||||
return;
|
||||
if (NULL == transfer)
|
||||
return;
|
||||
if (NULL == control)
|
||||
return;
|
||||
if (NULL == display)
|
||||
return;
|
||||
|
||||
bytes_since_last = 0;
|
||||
if (transfer->transferred >= 0) {
|
||||
bytes_since_last = transfer->transferred - calc->prev_transferred;
|
||||
calc->prev_transferred = transfer->transferred;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the time since the last update is very small, keep track of
|
||||
* the amount transferred since the last update, and just keep
|
||||
* adding to that until a reasonable amount of time has passed to
|
||||
* avoid rate spikes or division by zero.
|
||||
*/
|
||||
time_since_last = transfer->elapsed_seconds - calc->prev_elapsed_sec;
|
||||
if (time_since_last <= 0.01) {
|
||||
transfer_rate = calc->prev_rate;
|
||||
calc->prev_trans += bytes_since_last;
|
||||
} else {
|
||||
long double measured_rate;
|
||||
|
||||
transfer_rate = ((long double) bytes_since_last + calc->prev_trans) / time_since_last;
|
||||
measured_rate = transfer_rate;
|
||||
|
||||
calc->prev_elapsed_sec = transfer->elapsed_seconds;
|
||||
calc->prev_trans = 0;
|
||||
|
||||
if ((calc->measurements_taken < 1) || (measured_rate < calc->rate_min)) {
|
||||
calc->rate_min = measured_rate;
|
||||
}
|
||||
if (measured_rate > calc->rate_max) {
|
||||
calc->rate_max = measured_rate;
|
||||
}
|
||||
calc->rate_sum += measured_rate;
|
||||
calc->ratesquared_sum += (measured_rate * measured_rate);
|
||||
calc->measurements_taken++;
|
||||
}
|
||||
calc->prev_rate = transfer_rate;
|
||||
|
||||
/* Update the history and current average rate. */
|
||||
pv__update_average_rate_history(calc, transfer, control->history_interval, transfer_rate);
|
||||
average_rate = calc->current_avg_rate;
|
||||
|
||||
/*
|
||||
* If this is the final update at the end of the transfer,
|
||||
* recalculate the rate - and the average rate - across the whole
|
||||
* period of the transfer.
|
||||
*/
|
||||
if (final) {
|
||||
long double total_elapsed_seconds = (long double) (transfer->elapsed_seconds);
|
||||
/* Safety check to avoid division by zero. */
|
||||
if (total_elapsed_seconds < 0.000001)
|
||||
total_elapsed_seconds = 0.000001;
|
||||
average_rate =
|
||||
(((long double) (transfer->transferred)) -
|
||||
((long double) display->initial_offset)) / total_elapsed_seconds;
|
||||
transfer_rate = average_rate;
|
||||
}
|
||||
|
||||
calc->transfer_rate = transfer_rate;
|
||||
calc->average_rate = average_rate;
|
||||
|
||||
if (control->size <= 0) {
|
||||
/*
|
||||
* If the total size of the incoming data is unknown, then
|
||||
* for a percentage, gradually increase the percentage
|
||||
* completion as data arrives, to a maximum of 200, then
|
||||
* reset it. This means that the numeric percentage output
|
||||
* will go 0%-100%, 100%-0%, 0%-100%, and so on.
|
||||
*/
|
||||
if (transfer_rate > 0)
|
||||
calc->percentage += 2;
|
||||
if (calc->percentage > 199)
|
||||
calc->percentage = 0;
|
||||
} else {
|
||||
calc->percentage = pv_percentage(transfer->transferred, control->size);
|
||||
}
|
||||
|
||||
/* Ensure the percentage is never negative or huge. */
|
||||
if (calc->percentage < 0.0)
|
||||
calc->percentage = 0.0;
|
||||
if (calc->percentage > 100000.0)
|
||||
calc->percentage = 100000.0;
|
||||
}
|
||||
+394
-224
@@ -7,12 +7,12 @@
|
||||
* first `pv' process.
|
||||
*
|
||||
* However, some OSes (FreeBSD and MacOS X so far) don't allow locking of a
|
||||
* terminal, so we try to use a lockfile if terminal locking doesn't work,
|
||||
* and finally abort if even that is unavailable.
|
||||
* terminal - so if terminal locking doesn't work, a separate lock file is
|
||||
* used, and cursor positioning is abandoned if that also fails.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -35,76 +35,86 @@
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
/* for basename() */
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
|
||||
/*
|
||||
* Write the given buffer to the given file descriptor, retrying until all
|
||||
* bytes have been written or an error has occurred.
|
||||
* Flag to allow reporting of "interrupted by signal" errors - cleared in
|
||||
* secondary instances in a pipeline, so that only one will report them.
|
||||
*/
|
||||
void pv_write_retry(int fd, const char *buf, size_t count)
|
||||
{
|
||||
while (count > 0) {
|
||||
ssize_t nwritten;
|
||||
|
||||
nwritten = write(fd, buf, count);
|
||||
|
||||
if (nwritten < 0) {
|
||||
if ((EINTR == errno) || (EAGAIN == errno)) {
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (nwritten < 1)
|
||||
return;
|
||||
|
||||
count -= nwritten;
|
||||
buf += nwritten;
|
||||
}
|
||||
}
|
||||
static bool pv__allow_signal_interrupt_reporting = true;
|
||||
|
||||
|
||||
/*
|
||||
* Create a per-euid, per-tty, lockfile in ${TMPDIR:-${TMP:-/tmp}} for the
|
||||
* Create a per-euid, per-tty, lock file in ${TMPDIR:-${TMP:-/tmp}} for the
|
||||
* tty on the given file descriptor.
|
||||
*/
|
||||
static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
static void pv_crs_open_lockfile(pvcursorstate_t cursor, readonly_pvcontrol_t control, int fd)
|
||||
{
|
||||
char *ttydev;
|
||||
char *tmpdir;
|
||||
int openflags;
|
||||
|
||||
state->crs_lock_fd = -1;
|
||||
cursor->lock_fd = -1;
|
||||
|
||||
ttydev = ttyname(fd);
|
||||
if (!ttydev) {
|
||||
if (!state->force) {
|
||||
pv_error(state, "%s: %s", _("failed to get terminal name"), strerror(errno));
|
||||
/*
|
||||
* Note that a copy is made of result of ttyname(), so it's not in a
|
||||
* static buffer, because basename() may modify it.
|
||||
*/
|
||||
|
||||
ttydev = pv_strdup(ttyname(fd));
|
||||
if (NULL == ttydev) {
|
||||
if (!control->force) {
|
||||
/*
|
||||
* Error not translated as this should never be
|
||||
* reached, since ttyname() will have been called
|
||||
* earlier, and if it failed, cursor positioning
|
||||
* would have been turned off.
|
||||
*/
|
||||
pv_perror("%s", "ttyname");
|
||||
}
|
||||
/*
|
||||
* If we don't know our terminal name, we can neither do IPC
|
||||
* nor make a lock file, so turn off cursor positioning.
|
||||
* If the terminal name is unknown, then neither IPC nor a
|
||||
* lock file are feasible, so turn off cursor positioning.
|
||||
*/
|
||||
state->cursor = 0;
|
||||
cursor->disable = true;
|
||||
debug("%s", "ttyname failed - cursor positioning disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
tmpdir = (char *) getenv("TMPDIR");
|
||||
if (!tmpdir)
|
||||
tmpdir = (char *) getenv("TMP");
|
||||
if (!tmpdir)
|
||||
tmpdir = (char *) getenv("TMPDIR"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = (char *) getenv("TMP"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = "/tmp";
|
||||
|
||||
memset(state->crs_lock_file, 0, PV_SIZEOF_CRS_LOCK_FILE);
|
||||
(void) pv_snprintf(state->crs_lock_file,
|
||||
PV_SIZEOF_CRS_LOCK_FILE, "%s/pv-%s-%i.lock", tmpdir, basename(ttydev), (int) geteuid());
|
||||
/*
|
||||
* flawfinder rationale: null and zero-size values of $TMPDIR and
|
||||
* $TMP are rejected, and the destination buffer is bounded.
|
||||
*/
|
||||
|
||||
if (NULL != cursor->lock_file) {
|
||||
free(cursor->lock_file);
|
||||
cursor->lock_file = NULL;
|
||||
}
|
||||
(void) pv_asprintf(&(cursor->lock_file), "%s/pv-%s-%i.lock", tmpdir, basename(ttydev), (int) geteuid());
|
||||
|
||||
if (NULL == cursor->lock_file) {
|
||||
pv_perror("%s: %s", ttydev, _("failed to open lock file"));
|
||||
free(ttydev);
|
||||
cursor->disable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
free(ttydev);
|
||||
|
||||
/*
|
||||
* Pawel Piatek - not everyone has O_NOFOLLOW, e.g. AIX doesn't
|
||||
* Pawel Piatek - not everyone has O_NOFOLLOW, e.g. AIX doesn't.
|
||||
*/
|
||||
#ifdef O_NOFOLLOW
|
||||
openflags = O_RDWR | O_CREAT | O_NOFOLLOW;
|
||||
@@ -112,10 +122,18 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
openflags = O_RDWR | O_CREAT;
|
||||
#endif
|
||||
|
||||
state->crs_lock_fd = open(state->crs_lock_file, openflags, 0600);
|
||||
if (state->crs_lock_fd < 0) {
|
||||
pv_error(state, "%s: %s: %s", state->crs_lock_file, _("failed to open lock file"), strerror(errno));
|
||||
state->cursor = 0;
|
||||
cursor->lock_fd = open(cursor->lock_file, openflags, 0600); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale: the file isn't being truncated and its
|
||||
* contents won't be changed, and O_NOFOLLOW will be used if
|
||||
* available (to avoid symlink attacks), so this open() has been made
|
||||
* as safe as possible.
|
||||
*/
|
||||
|
||||
if (cursor->lock_fd < 0) {
|
||||
pv_perror("%s: %s", cursor->lock_file, _("failed to open lock file"));
|
||||
cursor->disable = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -123,16 +141,16 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
|
||||
/*
|
||||
* Lock the terminal on the given file descriptor, falling back to using a
|
||||
* lockfile if the terminal itself cannot be locked.
|
||||
* lock file if the terminal itself cannot be locked.
|
||||
*/
|
||||
static void pv_crs_lock(pvstate_t state, int fd)
|
||||
static void pv_crs_lock(pvcursorstate_t cursor, readonly_pvcontrol_t control, int fd)
|
||||
{
|
||||
struct flock lock;
|
||||
int lock_fd;
|
||||
|
||||
lock_fd = fd;
|
||||
if (state->crs_lock_fd >= 0)
|
||||
lock_fd = state->crs_lock_fd;
|
||||
if (cursor->lock_fd >= 0)
|
||||
lock_fd = cursor->lock_fd;
|
||||
|
||||
memset(&lock, 0, sizeof(lock));
|
||||
lock.l_type = (short) F_WRLCK;
|
||||
@@ -141,20 +159,21 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
lock.l_len = 1;
|
||||
while (fcntl(lock_fd, F_SETLKW, &lock) < 0) {
|
||||
if (errno != EINTR) {
|
||||
if (state->crs_lock_fd == -2) {
|
||||
pv_crs_open_lockfile(state, fd);
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
lock_fd = state->crs_lock_fd;
|
||||
if (cursor->lock_fd == -2) {
|
||||
pv_crs_open_lockfile(cursor, control, fd);
|
||||
if (cursor->lock_fd >= 0) {
|
||||
lock_fd = cursor->lock_fd;
|
||||
}
|
||||
} else {
|
||||
pv_error(state, "%s: %s", _("lock attempt failed"), strerror(errno));
|
||||
pv_perror("%s", NULL == cursor->lock_file ? "(tty)" : cursor->lock_file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
debug("%s: %s", state->crs_lock_file, "terminal lockfile acquired");
|
||||
if (cursor->lock_fd >= 0) {
|
||||
debug("%s: %s", NULL == cursor->lock_file ? "(null)" : cursor->lock_file,
|
||||
"terminal lock file acquired");
|
||||
} else {
|
||||
debug("%s", "terminal lock acquired");
|
||||
}
|
||||
@@ -163,16 +182,16 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
|
||||
/*
|
||||
* Unlock the terminal on the given file descriptor. If pv_crs_lock used
|
||||
* lockfile locking, unlock the lockfile.
|
||||
* lock file locking, unlock the lock file.
|
||||
*/
|
||||
static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
static void pv_crs_unlock(pvcursorstate_t cursor, int fd)
|
||||
{
|
||||
struct flock lock;
|
||||
int lock_fd;
|
||||
|
||||
lock_fd = fd;
|
||||
if (state->crs_lock_fd >= 0)
|
||||
lock_fd = state->crs_lock_fd;
|
||||
if (cursor->lock_fd >= 0)
|
||||
lock_fd = cursor->lock_fd;
|
||||
|
||||
memset(&lock, 0, sizeof(lock));
|
||||
lock.l_type = (short) F_UNLCK;
|
||||
@@ -181,8 +200,9 @@ static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
lock.l_len = 1;
|
||||
(void) fcntl(lock_fd, F_SETLK, &lock);
|
||||
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
debug("%s: %s", state->crs_lock_file, "terminal lockfile released");
|
||||
if (cursor->lock_fd >= 0) {
|
||||
debug("%s: %s", NULL == cursor->lock_file ? "(null)" : cursor->lock_file,
|
||||
"terminal lock file released");
|
||||
} else {
|
||||
debug("%s", "terminal lock released");
|
||||
}
|
||||
@@ -193,23 +213,23 @@ static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
/*
|
||||
* Get the current number of processes attached to our shared memory
|
||||
* segment, i.e. find out how many `pv' processes in total are running in
|
||||
* cursor mode (including us), and store it in pv_crs_pvcount. If this is
|
||||
* larger than pv_crs_pvmax, update pv_crs_pvmax.
|
||||
* cursor mode (including this process), and store it in pv_crs_pvcount. If
|
||||
* this is larger than pv_crs_pvmax, update pv_crs_pvmax.
|
||||
*/
|
||||
static void pv_crs_ipccount(pvstate_t state)
|
||||
static void pv_crs_ipccount(pvcursorstate_t cursor)
|
||||
{
|
||||
struct shmid_ds buf;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.shm_nattch = 0;
|
||||
|
||||
(void) shmctl(state->crs_shmid, IPC_STAT, &buf);
|
||||
state->crs_pvcount = (int) (buf.shm_nattch);
|
||||
(void) shmctl(cursor->shmid, IPC_STAT, &buf);
|
||||
cursor->pvcount = (int) (buf.shm_nattch);
|
||||
|
||||
if (state->crs_pvcount > state->crs_pvmax)
|
||||
state->crs_pvmax = state->crs_pvcount;
|
||||
if (cursor->pvcount > cursor->pvmax)
|
||||
cursor->pvmax = cursor->pvcount;
|
||||
|
||||
debug("%s: %d", "pvcount", state->crs_pvcount);
|
||||
debug("%s: %d", "pvcount", cursor->pvcount);
|
||||
}
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
@@ -217,12 +237,17 @@ static void pv_crs_ipccount(pvstate_t state)
|
||||
/*
|
||||
* Get the current cursor Y co-ordinate by sending the ECMA-48 CPR code to
|
||||
* the terminal connected to the given file descriptor.
|
||||
*
|
||||
* This should only be called while the terminal is locked, to avoid
|
||||
* confusing other "pv -c" instances about the current terminal attributes,
|
||||
* since this function temporarily changes the terminal attributes and then
|
||||
* puts them back.
|
||||
*/
|
||||
static int pv_crs_get_ypos(int terminalfd)
|
||||
{
|
||||
struct termios tty;
|
||||
struct termios old_tty;
|
||||
char cpr[32];
|
||||
char cpr[32]; /* flawfinder: ignore - bounded, zeroed */
|
||||
int ypos;
|
||||
ssize_t r;
|
||||
#ifdef CURSOR_ANSWERBACK_BYTE_BY_BYTE
|
||||
@@ -245,9 +270,10 @@ static int pv_crs_get_ypos(int terminalfd)
|
||||
memset(cpr, 0, sizeof(cpr));
|
||||
|
||||
#ifdef CURSOR_ANSWERBACK_BYTE_BY_BYTE
|
||||
/* Read answerback byte by byte - fails on AIX */
|
||||
/* Read answerback byte by byte - fails on AIX. */
|
||||
for (got = 0, r = 0; got < (int) (sizeof(cpr) - 2); got += r) {
|
||||
r = read(terminalfd, cpr + got, 1);
|
||||
r = read(terminalfd, cpr + got, 1); /* flawfinder: ignore */
|
||||
/* flawfinder rationale: bounded to buffer size by "for" */
|
||||
if (r <= 0) {
|
||||
debug("got=%d, r=%d: %s", got, r, strerror(errno));
|
||||
break;
|
||||
@@ -261,8 +287,9 @@ static int pv_crs_get_ypos(int terminalfd)
|
||||
terminalfd, got, cpr[0], cpr[1], cpr[2], cpr[3], cpr[4], cpr[5]);
|
||||
|
||||
#else /* !CURSOR_ANSWERBACK_BYTE_BY_BYTE */
|
||||
/* Read answerback in one big lump - may fail on Solaris */
|
||||
r = read(terminalfd, cpr, sizeof(cpr));
|
||||
/* Read answerback in one big lump - may fail on Solaris. */
|
||||
r = read(terminalfd, cpr, sizeof(cpr) - 2); /* flawfinder: ignore */
|
||||
/* flawfinder rationale: bounded to buffer size. */
|
||||
if (r <= 0) {
|
||||
debug("r=%d: %s", r, strerror(errno));
|
||||
} else {
|
||||
@@ -271,9 +298,9 @@ static int pv_crs_get_ypos(int terminalfd)
|
||||
terminalfd, r, cpr[0], cpr[1], cpr[2], cpr[3], cpr[4], cpr[5]);
|
||||
|
||||
}
|
||||
#endif /* CURSOR_ANSWERBACK_BYTE_BY_BYTE */
|
||||
#endif /* !CURSOR_ANSWERBACK_BYTE_BY_BYTE */
|
||||
|
||||
ypos = (int) pv_getnum_ui(cpr + 2);
|
||||
ypos = (int) pv_getnum_count(cpr + 2, false);
|
||||
|
||||
if (0 != tcsetattr(terminalfd, TCSANOW | TCSAFLUSH, &old_tty)) {
|
||||
debug("%s: %s", "tcsetattr (2) failed", strerror(errno));
|
||||
@@ -289,23 +316,24 @@ static int pv_crs_get_ypos(int terminalfd)
|
||||
/*
|
||||
* Initialise the IPC data, returning nonzero on error.
|
||||
*
|
||||
* To do this, we attach to the shared memory segment (creating it if it
|
||||
* does not exist). If we are the only process attached to it, then we
|
||||
* initialise it with the current cursor position.
|
||||
* Attaches to the shared memory segment (creating it if it does not exist).
|
||||
* If this is the only process attached to it, then the memory is
|
||||
* initialised with the current cursor position.
|
||||
*
|
||||
* There is a race condition here: another process could attach before we've
|
||||
* had a chance to check, such that no process ends up getting an "attach
|
||||
* count" of one, and so no initialisation occurs. So, we lock the terminal
|
||||
* with pv_crs_lock() while we are attaching and checking.
|
||||
* To avoid a race condition, this function locks the terminal with
|
||||
* pv_crs_lock() while attaching and checking. The race condition is that
|
||||
* another process could attach before this one checks, such that no process
|
||||
* ends up getting an "attach count" of one, and so no initialisation
|
||||
* occurs.
|
||||
*/
|
||||
static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
static int pv_crs_ipcinit(pvcursorstate_t cursor, readonly_pvcontrol_t control, char *ttyfile, int terminalfd)
|
||||
{
|
||||
key_t key;
|
||||
|
||||
/*
|
||||
* Base the key for the shared memory segment on our current tty, so
|
||||
* we don't end up interfering in any way with instances of `pv'
|
||||
* running on another terminal.
|
||||
* Base the key for the shared memory segment on the current tty, to
|
||||
* avoid interfering in any way with instances of `pv' running on
|
||||
* another terminal.
|
||||
*/
|
||||
key = ftok(ttyfile, (int) 'p');
|
||||
if (-1 == key) {
|
||||
@@ -313,50 +341,63 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
pv_crs_lock(state, terminalfd);
|
||||
if (!state->cursor) {
|
||||
pv_crs_lock(cursor, control, terminalfd);
|
||||
if ((!control->cursor) || (cursor->disable)) {
|
||||
debug("%s", "early return - cursor has been disabled");
|
||||
return 1;
|
||||
}
|
||||
|
||||
state->crs_shmid = shmget(key, sizeof(int), 0600 | IPC_CREAT);
|
||||
if (state->crs_shmid < 0) {
|
||||
cursor->shmid = shmget(key, sizeof(struct pvipccursorstate_s), 0600 | IPC_CREAT);
|
||||
if (cursor->shmid < 0) {
|
||||
debug("%s: %s", "shmget failed", strerror(errno));
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
pv_crs_unlock(cursor, terminalfd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
state->crs_y_top = shmat(state->crs_shmid, NULL, 0);
|
||||
/*@-nullpass@ */
|
||||
/* splint doesn't know shmaddr can be NULL. */
|
||||
cursor->shared = shmat(cursor->shmid, NULL, 0);
|
||||
/*@+nullpass@ */
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
pv_crs_ipccount(cursor);
|
||||
|
||||
/*
|
||||
* If nobody else is attached to the shared memory segment, we're
|
||||
* the first, so we need to initialise the shared memory with our
|
||||
* current Y cursor co-ordinate.
|
||||
* If no other process is attached to the shared memory segment,
|
||||
* this one is the first, so initialise the shared memory with the
|
||||
* current Y cursor co-ordinate and with an initial false value for
|
||||
* the TOSTOP-added flag.
|
||||
*/
|
||||
if (state->crs_pvcount < 2) {
|
||||
state->crs_y_start = pv_crs_get_ypos(terminalfd);
|
||||
*(state->crs_y_top) = state->crs_y_start;
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
if (cursor->pvcount < 2) {
|
||||
cursor->y_start = pv_crs_get_ypos(terminalfd);
|
||||
cursor->shared->y_topmost = cursor->y_start;
|
||||
cursor->shared->tty_tostop_added = false;
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
debug("%s", "we are the first to attach");
|
||||
} else {
|
||||
/*
|
||||
* Another process was first, so prevent the current
|
||||
* instance from reporting "interrupted by signal" errors
|
||||
* since the first one will do that.
|
||||
*/
|
||||
debug("%s", "not the first to attach - clearing pv__allow_signal_interrupt_reporting");
|
||||
pv__allow_signal_interrupt_reporting = false;
|
||||
}
|
||||
|
||||
state->crs_y_offset = state->crs_pvcount - 1;
|
||||
if (state->crs_y_offset < 0)
|
||||
state->crs_y_offset = 0;
|
||||
cursor->y_offset = cursor->pvcount - 1;
|
||||
if (cursor->y_offset < 0)
|
||||
cursor->y_offset = 0;
|
||||
|
||||
/*
|
||||
* If anyone else had attached to the shared memory segment, we need
|
||||
* to read the top Y co-ordinate from it.
|
||||
* If any other process had attached to the shared memory segment
|
||||
* already, read the top Y co-ordinate from it.
|
||||
*/
|
||||
if (state->crs_pvcount > 1) {
|
||||
state->crs_y_start = *(state->crs_y_top);
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
debug("%s: %d", "not the first to attach - got top y", state->crs_y_start);
|
||||
if (cursor->pvcount > 1) {
|
||||
cursor->y_start = cursor->shared->y_topmost;
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
debug("%s: %d", "not the first to attach - got top y", cursor->y_start);
|
||||
}
|
||||
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
pv_crs_unlock(cursor, terminalfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -366,260 +407,389 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
/*
|
||||
* Initialise the terminal for cursor positioning.
|
||||
*/
|
||||
void pv_crs_init(pvstate_t state)
|
||||
void pv_crs_init(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags)
|
||||
{
|
||||
char *ttyfile;
|
||||
int fd;
|
||||
int terminalfd;
|
||||
|
||||
state->crs_lock_fd = -2;
|
||||
state->crs_lock_file[0] = '\0';
|
||||
cursor->lock_fd = -2;
|
||||
if (NULL != cursor->lock_file) {
|
||||
free(cursor->lock_file);
|
||||
cursor->lock_file = NULL;
|
||||
}
|
||||
|
||||
if (!state->cursor)
|
||||
if ((!control->cursor) || (cursor->disable))
|
||||
return;
|
||||
|
||||
debug("%s", "init");
|
||||
|
||||
ttyfile = ttyname(STDERR_FILENO);
|
||||
if (!ttyfile) {
|
||||
if (NULL == ttyfile) {
|
||||
debug("%s: %s", "disabling cursor positioning because ttyname failed", strerror(errno));
|
||||
state->cursor = 0;
|
||||
cursor->disable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
fd = open(ttyfile, O_RDWR);
|
||||
if (fd < 0) {
|
||||
pv_error(state, "%s: %s: %s", _("failed to open terminal"), ttyfile, strerror(errno));
|
||||
state->cursor = false;
|
||||
terminalfd = open(ttyfile, O_RDWR); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale: the file won't be truncated but could be
|
||||
* corrupted by writes attempting to get the current Y position; but
|
||||
* the filename is from ttyname() and it could be a symbolic link,
|
||||
* so O_NOFOLLOW isn't feasible and it has to be trusted as-is.
|
||||
*/
|
||||
|
||||
if (terminalfd < 0) {
|
||||
pv_perror("%s", ttyfile);
|
||||
cursor->disable = true;
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_IPC
|
||||
if (pv_crs_ipcinit(state, ttyfile, fd) != 0) {
|
||||
if (pv_crs_ipcinit(cursor, control, ttyfile, terminalfd) != 0) {
|
||||
debug("%s", "ipcinit failed, setting noipc flag");
|
||||
state->crs_noipc = true;
|
||||
cursor->noipc = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are not using IPC, then we need to get the current Y
|
||||
* co-ordinate. If we are using IPC, then the pv_crs_ipcinit()
|
||||
* function takes care of this in a more multi-process-friendly way.
|
||||
* If the terminal TOSTOP attribute was already set by this process,
|
||||
* set the flag in shared memory to let the other instances know.
|
||||
*/
|
||||
if (state->crs_noipc) {
|
||||
if ((!cursor->noipc) && (1 == flags->clear_tty_tostop_on_exit) && (NULL != cursor->shared)) {
|
||||
debug("%s", "propagating local clear_tty_tostop_on_exit true value to shared tty_tostop_added flag");
|
||||
cursor->shared->tty_tostop_added = true;
|
||||
}
|
||||
|
||||
#ifdef ECHOCTL
|
||||
/*
|
||||
* If the terminal ECHOCTL attribute was already cleared by this
|
||||
* process, set the flag in shared memory to let the other instances
|
||||
* know.
|
||||
*/
|
||||
if ((!cursor->noipc) && (1 == flags->set_tty_echoctl_on_exit) && (NULL != cursor->shared)) {
|
||||
debug("%s", "propagating local set_tty_echoctl_on_exit true value to shared tty_echoctl_cleared flag");
|
||||
cursor->shared->tty_echoctl_cleared = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If IPC is not being used, the current Y needs to be determined.
|
||||
* If IPC is being used, then the pv_crs_ipcinit() function takes
|
||||
* care of this in a more multi-process-friendly way.
|
||||
*/
|
||||
if (cursor->noipc) {
|
||||
#else /* ! HAVE_IPC */
|
||||
if (1) {
|
||||
#endif /* HAVE_IPC */
|
||||
/*
|
||||
* Get current cursor position + 1.
|
||||
*/
|
||||
pv_crs_lock(state, fd);
|
||||
state->crs_y_start = pv_crs_get_ypos(fd);
|
||||
pv_crs_lock(cursor, control, terminalfd);
|
||||
cursor->y_start = pv_crs_get_ypos(terminalfd);
|
||||
/*
|
||||
* Move down a line while the terminal is locked, so that
|
||||
* other processes in the pipeline will get a different
|
||||
* initial ypos.
|
||||
*/
|
||||
if (state->crs_y_start > 0)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_crs_unlock(state, fd);
|
||||
if (cursor->y_start > 0)
|
||||
pv_tty_write(flags, "\n", 1);
|
||||
pv_crs_unlock(cursor, terminalfd);
|
||||
|
||||
if (state->crs_y_start < 1)
|
||||
state->cursor = 0;
|
||||
if (cursor->y_start < 1)
|
||||
cursor->disable = true;
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
(void) close(terminalfd);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
/*
|
||||
* Set the "we need to reinitialise cursor positioning" flag.
|
||||
* Set the "need to reinitialise cursor positioning" flag.
|
||||
*/
|
||||
void pv_crs_needreinit(pvstate_t state)
|
||||
void pv_crs_needreinit(pvcursorstate_t cursor)
|
||||
{
|
||||
state->crs_needreinit += 2;
|
||||
if (state->crs_needreinit > 3)
|
||||
state->crs_needreinit = 3;
|
||||
cursor->needreinit += 2;
|
||||
if (cursor->needreinit > 3)
|
||||
cursor->needreinit = 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
/*
|
||||
* Reinitialise the cursor positioning code (called if we are backgrounded
|
||||
* then foregrounded again).
|
||||
* Reinitialise the cursor positioning code (called if the process is
|
||||
* backgrounded then foregrounded again).
|
||||
*/
|
||||
void pv_crs_reinit(pvstate_t state)
|
||||
static void pv_crs_reinit(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags)
|
||||
{
|
||||
debug("%s", "reinit");
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
if (1 == flags->suspend_stderr) {
|
||||
debug("%s", "reinit abandoned - stderr is suspended");
|
||||
return;
|
||||
}
|
||||
|
||||
state->crs_needreinit--;
|
||||
if (state->crs_y_offset < 1)
|
||||
state->crs_needreinit = 0;
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
if (state->crs_needreinit > 0) {
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
cursor->needreinit--;
|
||||
if (cursor->y_offset < 1)
|
||||
cursor->needreinit = 0;
|
||||
|
||||
if (cursor->needreinit > 0) {
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
return;
|
||||
}
|
||||
|
||||
debug("%s", "reinit full");
|
||||
|
||||
state->crs_y_start = pv_crs_get_ypos(STDERR_FILENO);
|
||||
cursor->y_start = pv_crs_get_ypos(STDERR_FILENO);
|
||||
|
||||
if (state->crs_y_offset < 1)
|
||||
*(state->crs_y_top) = state->crs_y_start;
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
if ((cursor->y_offset < 1) && (NULL != cursor->shared)) {
|
||||
cursor->shared->y_topmost = cursor->y_start;
|
||||
}
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Output a single-line update, moving the cursor to the correct position to
|
||||
* do so.
|
||||
* Output a single-line update (\0-terminated), using the ECMA-48 CSI "CUP"
|
||||
* sequence to move the cursor to the correct position to do so.
|
||||
*/
|
||||
void pv_crs_update(pvstate_t state, const char *str)
|
||||
void pv_crs_update(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags,
|
||||
const char *output_line)
|
||||
{
|
||||
char pos[32];
|
||||
char cup_cmd[32]; /* flawfinder: ignore */
|
||||
size_t cup_cmd_length, output_line_length;
|
||||
int y;
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
if (!state->crs_noipc) {
|
||||
if (state->crs_needreinit > 0)
|
||||
pv_crs_reinit(state);
|
||||
/* Early return if cursor positioning was disabled. */
|
||||
if (cursor->disable)
|
||||
return;
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
if (state->crs_y_lastread != *(state->crs_y_top)) {
|
||||
state->crs_y_start = *(state->crs_y_top);
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
/*
|
||||
* flawfinder rationale: the "cup_cmd" buffer is always zeroed
|
||||
* before each use, and is only written to by pv_snprintf() bounded
|
||||
* by its size; also, that function explicitly zero-terminates the
|
||||
* string it writes. The write() call is also bounded.
|
||||
*/
|
||||
|
||||
output_line_length = strlen(output_line); /* flawfinder: ignore */
|
||||
/* flawfinder - output_line is explictly expected to be \0-terminated. */
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
if (!cursor->noipc) {
|
||||
if (cursor->needreinit > 0)
|
||||
pv_crs_reinit(cursor, control, flags);
|
||||
|
||||
pv_crs_ipccount(cursor);
|
||||
if (NULL != cursor->shared) {
|
||||
if (cursor->y_lastread != cursor->shared->y_topmost) {
|
||||
cursor->y_start = cursor->shared->y_topmost;
|
||||
cursor->y_lastread = cursor->y_start;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->crs_needreinit > 0)
|
||||
if (cursor->needreinit > 0)
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
y = state->crs_y_start;
|
||||
y = cursor->y_start;
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
/*
|
||||
* If the screen has scrolled, or is about to scroll, due to
|
||||
* multiple `pv' instances taking us near the bottom of the screen,
|
||||
* scroll the screen (only if we're the first `pv'), and then move
|
||||
* our initial Y co-ordinate up.
|
||||
* scroll the screen (only if this is the first `pv'), and then move
|
||||
* the initial Y co-ordinate up.
|
||||
*/
|
||||
if (((state->crs_y_start + state->crs_pvmax) > (int) (state->height))
|
||||
&& (!state->crs_noipc)
|
||||
if (((cursor->y_start + cursor->pvmax) > (int) (control->height))
|
||||
&& (!cursor->noipc)
|
||||
) {
|
||||
int offs;
|
||||
|
||||
offs = ((state->crs_y_start + state->crs_pvmax) - state->height);
|
||||
offs = ((cursor->y_start + cursor->pvmax) - control->height);
|
||||
|
||||
state->crs_y_start -= offs;
|
||||
if (state->crs_y_start < 1)
|
||||
state->crs_y_start = 1;
|
||||
cursor->y_start -= offs;
|
||||
if (cursor->y_start < 1)
|
||||
cursor->y_start = 1;
|
||||
|
||||
debug("%s: %d", "scroll offset", offs);
|
||||
|
||||
/*
|
||||
* Scroll the screen if we're the first `pv'.
|
||||
* Scroll the screen if this is the first `pv'.
|
||||
*/
|
||||
if (0 == state->crs_y_offset) {
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
if (0 == cursor->y_offset) {
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
memset(pos, 0, sizeof(pos));
|
||||
(void) pv_snprintf(pos, sizeof(pos), "\033[%u;1H", state->height);
|
||||
pv_write_retry(STDERR_FILENO, pos, strlen(pos));
|
||||
memset(cup_cmd, 0, sizeof(cup_cmd));
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H", control->height);
|
||||
cup_cmd_length = strlen(cup_cmd); /* flawfinder: ignore */
|
||||
pv_tty_write(flags, cup_cmd, cup_cmd_length);
|
||||
for (; offs > 0; offs--) {
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(flags, "\n", 1);
|
||||
}
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
|
||||
debug("%s", "we are the first - scrolled screen");
|
||||
}
|
||||
}
|
||||
|
||||
if (!state->crs_noipc)
|
||||
y = state->crs_y_start + state->crs_y_offset;
|
||||
if (!cursor->noipc)
|
||||
y = cursor->y_start + cursor->y_offset;
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
/*
|
||||
* Keep the Y co-ordinate within sensible bounds, so we can never
|
||||
* overflow the "pos" buffer.
|
||||
* Clamp the Y co-ordinate to sensible bounds, to avoid overflowing
|
||||
* the "cup_cmd" buffer.
|
||||
*/
|
||||
if ((y < 1) || (y > 999999))
|
||||
y = 1;
|
||||
|
||||
memset(pos, 0, sizeof(pos));
|
||||
(void) pv_snprintf(pos, sizeof(pos), "\033[%d;1H", y);
|
||||
memset(cup_cmd, 0, sizeof(cup_cmd));
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%d;1H", y);
|
||||
cup_cmd_length = strlen(cup_cmd); /* flawfinder: ignore */
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
/*
|
||||
* flawfinder rationale: "cup_cmd" is only written to by
|
||||
* pv_snprintf(), which explicitly ensures that the string will be
|
||||
* \0-terminated, and the buffer is zeroed beforehand so if
|
||||
* pv_snprintf() fails to run the string will be of zero length.
|
||||
*/
|
||||
|
||||
pv_write_retry(STDERR_FILENO, pos, strlen(pos));
|
||||
pv_write_retry(STDERR_FILENO, str, strlen(str));
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_tty_write(flags, cup_cmd, cup_cmd_length);
|
||||
pv_tty_write(flags, output_line, output_line_length);
|
||||
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reposition the cursor to a final position.
|
||||
*/
|
||||
void pv_crs_fini(pvstate_t state)
|
||||
void pv_crs_fini(pvcursorstate_t cursor, readonly_pvcontrol_t control, pvtransientflags_t flags)
|
||||
{
|
||||
char pos[32];
|
||||
char cup_cmd[32]; /* flawfinder: ignore */
|
||||
unsigned int y;
|
||||
|
||||
/* flawfinder - "cup_cmd" is zeroed, and only written by pv_snprintf(). */
|
||||
|
||||
debug("%s", "fini");
|
||||
|
||||
y = (unsigned int) (state->crs_y_start);
|
||||
y = (unsigned int) (cursor->y_start);
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
if ((state->crs_pvmax > 0) && (!state->crs_noipc))
|
||||
y += state->crs_pvmax - 1;
|
||||
if ((cursor->pvmax > 0) && (!cursor->noipc))
|
||||
y += cursor->pvmax - 1;
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
if (y > state->height)
|
||||
y = state->height;
|
||||
if (y > control->height)
|
||||
y = control->height;
|
||||
|
||||
/*
|
||||
* Absolute bounds check.
|
||||
* Clamp to reasonable values.
|
||||
*/
|
||||
if ((y < 1) || (y > 999999))
|
||||
y = 1;
|
||||
|
||||
memset(pos, 0, sizeof(pos));
|
||||
(void) pv_snprintf(pos, sizeof(pos), "\033[%u;1H\n", y);
|
||||
memset(cup_cmd, 0, sizeof(cup_cmd));
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H\n", y);
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
pv_crs_lock(cursor, control, STDERR_FILENO);
|
||||
|
||||
pv_write_retry(STDERR_FILENO, pos, strlen(pos));
|
||||
if (!cursor->disable) {
|
||||
pv_tty_write(flags, cup_cmd, strlen(cup_cmd)); /* flawfinder: ignore */
|
||||
}
|
||||
/* flawfinder - pv_snprintf() always \0-terminates (see above). */
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
pv_crs_ipccount(state);
|
||||
(void) shmdt((void *) state->crs_y_top);
|
||||
/*
|
||||
* If any other "pv -c" instances have set the terminal TOSTOP
|
||||
* attribute, set the local flag so pv_sig_fini() will know about
|
||||
* it.
|
||||
*/
|
||||
if ((!cursor->noipc) && (NULL != cursor->shared) && cursor->shared->tty_tostop_added) {
|
||||
if (0 == flags->clear_tty_tostop_on_exit) {
|
||||
debug("%s",
|
||||
"propagating shared tty_tostop_added true value to local clear_tty_tostop_on_exit flag");
|
||||
flags->clear_tty_tostop_on_exit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ECHOCTL
|
||||
/*
|
||||
* If any other "pv -c" instances have cleared the terminal ECHOCTL
|
||||
* attribute, set the local flag so pv_sig_fini() will know about
|
||||
* it.
|
||||
*/
|
||||
if ((!cursor->noipc) && (NULL != cursor->shared) && cursor->shared->tty_echoctl_cleared) {
|
||||
if (0 == flags->set_tty_echoctl_on_exit) {
|
||||
debug("%s",
|
||||
"propagating shared tty_echoctl_cleared true value to local set_tty_echoctl_on_exit flag");
|
||||
flags->set_tty_echoctl_on_exit = 1;
|
||||
}
|
||||
}
|
||||
#endif /* ECHOCTL */
|
||||
|
||||
pv_crs_ipccount(cursor);
|
||||
if (NULL != cursor->shared) {
|
||||
(void) shmdt(cursor->shared);
|
||||
}
|
||||
cursor->shared = NULL;
|
||||
|
||||
/*
|
||||
* If we are the last instance detaching from the shared memory,
|
||||
* If this is the last instance detaching from the shared memory,
|
||||
* delete it so it's not left lying around.
|
||||
*/
|
||||
if (state->crs_pvcount < 2)
|
||||
(void) shmctl(state->crs_shmid, IPC_RMID, NULL);
|
||||
if (cursor->pvcount < 2) {
|
||||
struct shmid_ds shm_buf;
|
||||
memset(&shm_buf, 0, sizeof(shm_buf));
|
||||
(void) shmctl(cursor->shmid, IPC_RMID, &shm_buf);
|
||||
}
|
||||
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
pv_crs_unlock(cursor, STDERR_FILENO);
|
||||
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
(void) close(state->crs_lock_fd);
|
||||
if (cursor->lock_fd >= 0) {
|
||||
(void) close(cursor->lock_fd);
|
||||
/*
|
||||
* We can get away with removing this on exit because all
|
||||
* the other PVs will be finishing at the same sort of time.
|
||||
* Since all PVs in a pipeline are likely to finish around
|
||||
* the same time, the lock file can be removed without
|
||||
* further co-ordination.
|
||||
*/
|
||||
(void) remove(state->crs_lock_file);
|
||||
if (NULL != cursor->lock_file) {
|
||||
(void) remove(cursor->lock_file);
|
||||
free(cursor->lock_file);
|
||||
cursor->lock_file = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
/*
|
||||
* Report a signal interrupt, unless the flag allowing it has been cleared
|
||||
* due to another instance already taking responsibility.
|
||||
*/
|
||||
void pv_report_signal_interrupt(int signum)
|
||||
{
|
||||
if (pv__allow_signal_interrupt_reporting) {
|
||||
char *signal_name = NULL;
|
||||
#ifdef HAVE_STRSIGNAL
|
||||
/*@-unrecog @ *//* splint doesn't know strsignal(). */
|
||||
signal_name = strsignal(signum);
|
||||
/*@+unrecog @ */
|
||||
#endif
|
||||
if (NULL != signal_name) {
|
||||
pv_error("%s: %s", _("interrupted by a signal"), signal_name);
|
||||
} else {
|
||||
pv_error("%s", _("interrupted by a signal"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1142
-762
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Functions relating to elapsed time.
|
||||
*
|
||||
* Copyright 2023-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/*
|
||||
* Read the current elapsed time, relative to an unspecified point in the
|
||||
* past, and store it in "return_time". The time is guaranteed to not go
|
||||
* backwards and does not count time when the system was suspended. See
|
||||
* clock_gettime(2) with CLOCK_MONOTONIC.
|
||||
*
|
||||
* The read should not fail; if it does, the program is aborted with exit
|
||||
* status 16 (transfer error).
|
||||
*/
|
||||
void pv_elapsedtime_read(struct timespec *return_time)
|
||||
{
|
||||
/*@-unrecog@ *//* splint doesn't know clock_gettime. */
|
||||
if (0 != clock_gettime(CLOCK_MONOTONIC, return_time)) {
|
||||
pv_perror("%s", "clock_gettime");
|
||||
/*@-exitarg@ *//* The special exit status is explicitly chosen. */
|
||||
exit(PV_ERROREXIT_TRANSFER);
|
||||
/*@+exitarg@ */
|
||||
}
|
||||
/*@+unrecog@ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the time in the timespec to zero.
|
||||
*/
|
||||
void pv_elapsedtime_zero(struct timespec *zero_time)
|
||||
{
|
||||
if (NULL == zero_time)
|
||||
return;
|
||||
zero_time->tv_sec = 0;
|
||||
zero_time->tv_nsec = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy source_time into dest_time. Analogous to strcpy(3).
|
||||
*/
|
||||
void pv_elapsedtime_copy(struct timespec *dest_time, const struct timespec *source_time)
|
||||
{
|
||||
if (NULL == dest_time)
|
||||
return;
|
||||
if (NULL == source_time)
|
||||
return;
|
||||
dest_time->tv_sec = source_time->tv_sec;
|
||||
dest_time->tv_nsec = source_time->tv_nsec;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return -1, 0, or 1 depending on whether the first time is earlier than,
|
||||
* equal to, or later than the second time. Analogous to strcmp(3).
|
||||
*/
|
||||
int pv_elapsedtime_compare(const struct timespec *first_time, const struct timespec *second_time)
|
||||
{
|
||||
/* Treat NULL as a zero time. */
|
||||
if ((NULL == first_time) && (NULL == second_time))
|
||||
return 0;
|
||||
if ((NULL == first_time) && (NULL != second_time))
|
||||
return -1;
|
||||
if ((NULL != first_time) && (NULL == second_time))
|
||||
return 1;
|
||||
|
||||
/* These should never happen, but check just in case. */
|
||||
if (NULL == first_time)
|
||||
return 0;
|
||||
if (NULL == second_time)
|
||||
return 0;
|
||||
|
||||
/* Check the seconds part, first */
|
||||
if (first_time->tv_sec < second_time->tv_sec)
|
||||
return -1;
|
||||
if (first_time->tv_sec > second_time->tv_sec)
|
||||
return 1;
|
||||
|
||||
/* Seconds are equal - compare nanoseconds. */
|
||||
if (first_time->tv_nsec < second_time->tv_nsec)
|
||||
return -1;
|
||||
if (first_time->tv_nsec > second_time->tv_nsec)
|
||||
return 1;
|
||||
|
||||
/* Nanoseconds are also equal - times are equal. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add first_time and second_time, writing the result to return_time.
|
||||
*/
|
||||
void pv_elapsedtime_add(struct timespec *return_time, const struct timespec *first_time,
|
||||
const struct timespec *second_time)
|
||||
{
|
||||
long long seconds, nanoseconds;
|
||||
|
||||
if (NULL == return_time)
|
||||
return;
|
||||
|
||||
seconds = 0;
|
||||
nanoseconds = 0;
|
||||
|
||||
if (NULL != first_time) {
|
||||
seconds += first_time->tv_sec;
|
||||
nanoseconds += first_time->tv_nsec;
|
||||
}
|
||||
|
||||
if (NULL != second_time) {
|
||||
seconds += second_time->tv_sec;
|
||||
nanoseconds += second_time->tv_nsec;
|
||||
}
|
||||
|
||||
seconds += nanoseconds / 1000000000;
|
||||
nanoseconds = nanoseconds % 1000000000;
|
||||
|
||||
/*@-type@ */
|
||||
return_time->tv_sec = seconds;
|
||||
return_time->tv_nsec = nanoseconds;
|
||||
/*@+type@ */
|
||||
|
||||
/*
|
||||
* splint rationale: the manual for timespec(3) states that its
|
||||
* types are implementation-defined, so the best option is to use
|
||||
* types that are the most likely to be large enough, and let the
|
||||
* compiler do the casting.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add a number of nanoseconds to a timespec.
|
||||
*/
|
||||
void pv_elapsedtime_add_nsec(struct timespec *return_time, long long add_nanoseconds)
|
||||
{
|
||||
long long seconds, nanoseconds;
|
||||
|
||||
if (NULL == return_time)
|
||||
return;
|
||||
|
||||
seconds = return_time->tv_sec;
|
||||
nanoseconds = return_time->tv_nsec + add_nanoseconds;
|
||||
|
||||
seconds += nanoseconds / 1000000000;
|
||||
nanoseconds = nanoseconds % 1000000000;
|
||||
|
||||
/*@-type@ *//* See above. */
|
||||
return_time->tv_sec = seconds;
|
||||
return_time->tv_nsec = nanoseconds;
|
||||
/*@+type@ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the return timespec to the first time minus the second time.
|
||||
*/
|
||||
void pv_elapsedtime_subtract(struct timespec *return_time, const struct timespec *first_time,
|
||||
const struct timespec *second_time)
|
||||
{
|
||||
long long seconds, nanoseconds;
|
||||
|
||||
if (NULL == return_time)
|
||||
return;
|
||||
|
||||
seconds = 0;
|
||||
nanoseconds = 0;
|
||||
|
||||
if (NULL != first_time) {
|
||||
seconds += first_time->tv_sec;
|
||||
nanoseconds += first_time->tv_nsec;
|
||||
}
|
||||
|
||||
if (NULL != second_time) {
|
||||
seconds -= second_time->tv_sec;
|
||||
nanoseconds -= second_time->tv_nsec;
|
||||
}
|
||||
|
||||
seconds += nanoseconds / 1000000000;
|
||||
nanoseconds = nanoseconds % 1000000000;
|
||||
|
||||
if (nanoseconds < 0) {
|
||||
seconds--;
|
||||
nanoseconds = 1000000000 + nanoseconds;
|
||||
}
|
||||
|
||||
/*@-type@ *//* See above. */
|
||||
return_time->tv_sec = seconds;
|
||||
return_time->tv_nsec = nanoseconds;
|
||||
/*@+type@ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert a timespec to seconds.
|
||||
*/
|
||||
long double pv_elapsedtime_seconds(const struct timespec *elapsed_time)
|
||||
{
|
||||
long double seconds;
|
||||
|
||||
if (NULL == elapsed_time)
|
||||
return 0.0;
|
||||
|
||||
seconds = (long double) elapsed_time->tv_sec;
|
||||
seconds += (long double) (elapsed_time->tv_nsec) / 1000000000.0L;
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sleep for a number of nanoseconds.
|
||||
*/
|
||||
void pv_nanosleep(long long nanoseconds)
|
||||
{
|
||||
#if HAVE_NANOSLEEP
|
||||
struct timespec sleep_for, time_remaining;
|
||||
|
||||
memset(&sleep_for, 0, sizeof(sleep_for));
|
||||
memset(&time_remaining, 0, sizeof(time_remaining));
|
||||
|
||||
sleep_for.tv_sec = 0;
|
||||
/*@-type@ */
|
||||
sleep_for.tv_nsec = nanoseconds;
|
||||
/*@+type@ *//* splint rationale - best effort. */
|
||||
/*@-unrecog@ */
|
||||
(void) nanosleep(&sleep_for, &time_remaining);
|
||||
/*@+unrecog@ *//* splint doesn't know of nanosleep(). */
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
/*@-type@ */
|
||||
tv.tv_usec = nanoseconds / 1000;
|
||||
/*@+type@ *//* splint rationale - best effort. */
|
||||
/*@-null@ */
|
||||
(void) select(0, NULL, NULL, NULL, &tv);
|
||||
/*@+null@ *//* splint doesn't know about select(). */
|
||||
#endif
|
||||
}
|
||||
+581
-157
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Functions for opening and closing files.
|
||||
* Functions for opening and closing files, and calculating their size.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -18,81 +18,169 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
|
||||
/*@-type@*/
|
||||
/* splint has trouble with off_t and mode_t throughout this file. */
|
||||
|
||||
/*
|
||||
* Check that a file descriptor is open on /dev/null, returning true if so.
|
||||
* Otherwise return false; if the second argument is true, reports the
|
||||
* problem with pv_error() before returning.
|
||||
*
|
||||
* No error is reported if the file descriptor is less than zero.
|
||||
*/
|
||||
bool pv_fd_is_dev_null(int fd, bool report_error)
|
||||
{
|
||||
struct stat sb;
|
||||
struct utsname uts;
|
||||
unsigned long expected_rdev;
|
||||
bool is_dev_null;
|
||||
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
if (fstat(fd, &sb) < 0) {
|
||||
if (report_error)
|
||||
pv_perror("%s", "/dev/null");
|
||||
return false;
|
||||
}
|
||||
|
||||
expected_rdev = 0x0103; /* device 1,3 on Linux. */
|
||||
|
||||
is_dev_null = true;
|
||||
if (!S_ISCHR(sb.st_mode)) {
|
||||
debug("%s", "/dev/null: not a character device");
|
||||
is_dev_null = false;
|
||||
}
|
||||
|
||||
memset(&uts, 0, sizeof(uts));
|
||||
if (uname(&uts) >= 0) {
|
||||
if (0 == strncmp(uts.sysname, "OpenBSD", 7)) {
|
||||
expected_rdev = 0x0202;
|
||||
} else if (0 == strncmp(uts.sysname, "FreeBSD", 7)) {
|
||||
expected_rdev = 0x0022;
|
||||
} else if (0 == strncmp(uts.sysname, "NetBSD", 6)) {
|
||||
expected_rdev = 0x0202;
|
||||
} else if (0 == strncmp(uts.sysname, "Darwin", 6)) {
|
||||
expected_rdev = 0x03000002;
|
||||
}
|
||||
}
|
||||
|
||||
if ((unsigned long) (sb.st_rdev) != expected_rdev) {
|
||||
debug("/dev/null: fd is %08lx, expected %08lx", sb.st_rdev, expected_rdev);
|
||||
is_dev_null = false;
|
||||
}
|
||||
|
||||
if (is_dev_null)
|
||||
return true;
|
||||
|
||||
if (report_error)
|
||||
pv_error("%s", _("/dev/null is not usable"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to work out the total size of all data by adding up the sizes of all
|
||||
* input files. If any of the input files are of indeterminate size (i.e.
|
||||
* they are a pipe), the total size is set to zero.
|
||||
* Calculate the total number of bytes to be transferred by adding up the
|
||||
* sizes of all input files. If any of the input files are of indeterminate
|
||||
* size (such as if they are a pipe), the total size is set to zero.
|
||||
*
|
||||
* Any files that cannot be stat()ed or that access() says we can't read
|
||||
* will cause a warning to be output and will be removed from the list.
|
||||
*
|
||||
* In line mode, any files that pass the above checks will then be read to
|
||||
* determine how many lines they contain, and the total size will be set to
|
||||
* the total line count. Only regular files will be read.
|
||||
* If there are any files that cannot be stat()ed, or that access() says are
|
||||
* not readable, they will be skipped, and the total size will be set to
|
||||
* zero.
|
||||
*
|
||||
* Returns the total size, or 0 if it is unknown.
|
||||
*/
|
||||
unsigned long long pv_calc_total_size(pvstate_t state)
|
||||
static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
{
|
||||
unsigned long long total;
|
||||
off_t total;
|
||||
struct stat sb;
|
||||
int rc, i, j, fd;
|
||||
unsigned int file_idx;
|
||||
|
||||
total = 0;
|
||||
rc = 0;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
|
||||
/*
|
||||
* No files specified - check stdin.
|
||||
*/
|
||||
if (state->input_file_count < 1) {
|
||||
if ((state->files.file_count < 1) || (NULL == state->files.filename)) {
|
||||
if (0 == fstat(STDIN_FILENO, &sb))
|
||||
total = sb.st_size;
|
||||
return total;
|
||||
}
|
||||
|
||||
for (i = 0; i < state->input_file_count; i++) {
|
||||
if (0 == strcmp(state->input_files[i], "-")) {
|
||||
for (file_idx = 0; file_idx < state->files.file_count; file_idx++) {
|
||||
int rc;
|
||||
|
||||
/* Skip any NULL entries, though they should be impossible. */
|
||||
if (NULL == state->files.filename[file_idx])
|
||||
continue;
|
||||
|
||||
if (0 == strcmp(state->files.filename[file_idx], "-")) {
|
||||
rc = fstat(STDIN_FILENO, &sb);
|
||||
if (rc != 0) {
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
} else {
|
||||
rc = stat(state->input_files[i], &sb);
|
||||
if (0 == rc)
|
||||
rc = access(state->input_files[i], R_OK);
|
||||
rc = stat(state->files.filename[file_idx], &sb);
|
||||
if (0 == rc) {
|
||||
rc = access(state->files.filename[file_idx], R_OK); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: access() can lead
|
||||
* to TOCTOU issues but here it isn't being
|
||||
* used to check permissions, only to zero
|
||||
* the total if the file is likely to be
|
||||
* unreadable later. If an attacker
|
||||
* redirected one of the input files in
|
||||
* between this part and the actual reading,
|
||||
* the outcome would be that the total byte
|
||||
* count would be wrong or missing, nothing
|
||||
* otherwise exploitable.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
pv_error(state, "%s: %s", state->input_files[i], strerror(errno));
|
||||
for (j = i; j < state->input_file_count - 1; j++) {
|
||||
state->input_files[j] = state->input_files[j + 1];
|
||||
}
|
||||
state->input_file_count--;
|
||||
i--;
|
||||
state->exit_status |= 2;
|
||||
continue;
|
||||
debug("%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
|
||||
if (S_ISBLK(sb.st_mode)) {
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Get the size of block devices by opening
|
||||
* them and seeking to the end.
|
||||
*/
|
||||
if (0 == strcmp(state->input_files[i], "-")) {
|
||||
fd = open("/dev/stdin", O_RDONLY);
|
||||
if (0 == strcmp(state->files.filename[file_idx], "-")) {
|
||||
fd = open("/dev/stdin", O_RDONLY); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: "/dev/stdin" may be
|
||||
* a symlink, so O_NOFOLLOW is not suitable;
|
||||
* in mitigation, a path under "/dev" is
|
||||
* unlikely to be under the control of
|
||||
* someone else.
|
||||
*/
|
||||
} else {
|
||||
fd = open(state->input_files[i], O_RDONLY);
|
||||
fd = open(state->files.filename[file_idx], O_RDONLY); /* flawfinder: ignore */
|
||||
/* flawfinder - see last open() below. */
|
||||
}
|
||||
if (fd >= 0) {
|
||||
total += lseek(fd, 0, SEEK_END);
|
||||
close(fd);
|
||||
off_t end_position;
|
||||
end_position = lseek(fd, 0, SEEK_END);
|
||||
if (end_position > 0) {
|
||||
total += end_position;
|
||||
}
|
||||
(void) close(fd);
|
||||
} else {
|
||||
pv_error(state, "%s: %s", state->input_files[i], strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
} else if (S_ISREG(sb.st_mode)) {
|
||||
total += sb.st_size;
|
||||
@@ -102,191 +190,527 @@ unsigned long long pv_calc_total_size(pvstate_t state)
|
||||
}
|
||||
|
||||
/*
|
||||
* Patch from Peter Samuelson: if we cannot work out the size of the
|
||||
* input, but we are writing to a block device, then use the size of
|
||||
* the output block device.
|
||||
* Patch from Peter Samuelson: if the input size can't be
|
||||
* determined, but the output is being written to a block device,
|
||||
* then use the size of the output block device.
|
||||
*
|
||||
* Further modified to check that stdout is not in append-only mode
|
||||
* and that we can seek back to the start after getting the size.
|
||||
* Further modified to check that output is not in append-only mode,
|
||||
* such that it is possible to seek back to the start after getting
|
||||
* the size.
|
||||
*/
|
||||
if (total <= 0) {
|
||||
rc = fstat(STDOUT_FILENO, &sb);
|
||||
if (total < 1) {
|
||||
int rc;
|
||||
|
||||
rc = fstat(state->control.output_fd, &sb);
|
||||
|
||||
if ((0 == rc) && S_ISBLK(sb.st_mode)
|
||||
&& (0 == (fcntl(STDOUT_FILENO, F_GETFL) & O_APPEND))) {
|
||||
total = lseek(STDOUT_FILENO, 0, SEEK_END);
|
||||
if (lseek(STDOUT_FILENO, 0, SEEK_SET) != 0) {
|
||||
pv_error(state, "%s: %s: %s", "(stdout)",
|
||||
_("failed to seek to start of output"), strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
&& (0 == (fcntl(state->control.output_fd, F_GETFL) & O_APPEND))) {
|
||||
off_t end_position;
|
||||
end_position = lseek(state->control.output_fd, 0, SEEK_END);
|
||||
total = 0;
|
||||
if (end_position > 0) {
|
||||
total = end_position;
|
||||
}
|
||||
if (lseek(state->control.output_fd, 0, SEEK_SET) != 0) {
|
||||
pv_perror("%s",
|
||||
NULL == state->control.output_name ? "(null)" : state->control.output_name);
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
/*
|
||||
* If we worked out a size, then set the
|
||||
* stop-at-size flag to prevent a "no space left on
|
||||
* device" error when we reach the end of the output
|
||||
* device.
|
||||
* If a size was found, then set the stop-at-size
|
||||
* flag to prevent a "no space left on device" error
|
||||
* when the end of the output device is reached.
|
||||
*/
|
||||
if (total > 0) {
|
||||
state->stop_at_size = 1;
|
||||
state->control.stop_at_size = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!state->linemode)
|
||||
return total;
|
||||
|
||||
/*
|
||||
* In line mode, we count input lines to work out the total size.
|
||||
*/
|
||||
total = 0;
|
||||
|
||||
for (i = 0; i < state->input_file_count; i++) {
|
||||
fd = -1;
|
||||
|
||||
if (0 == strcmp(state->input_files[i], "-")) {
|
||||
rc = fstat(STDIN_FILENO, &sb);
|
||||
if ((rc != 0) || (!S_ISREG(sb.st_mode))) {
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
fd = dup(STDIN_FILENO);
|
||||
} else {
|
||||
rc = stat(state->input_files[i], &sb);
|
||||
if ((rc != 0) || (!S_ISREG(sb.st_mode))) {
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
fd = open(state->input_files[i], O_RDONLY);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
pv_error(state, "%s: %s", state->input_files[i], strerror(errno));
|
||||
total = 0;
|
||||
state->exit_status |= 2;
|
||||
return total;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
unsigned char scanbuf[1024];
|
||||
int numread, j;
|
||||
|
||||
numread = read(fd, scanbuf, sizeof(scanbuf));
|
||||
if (numread < 0) {
|
||||
pv_error(state, "%s: %s", state->input_files[i], strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
break;
|
||||
} else if (0 == numread) {
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < numread; j++) {
|
||||
if ('\n' == scanbuf[j])
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Count the total number of lines to be transferred by reading through all
|
||||
* input files. If any of the inputs are not regular files (such as if they
|
||||
* are a pipe or a block device), the total size is set to zero.
|
||||
*
|
||||
* If there are any files that cannot be stat()ed, or that access() says are
|
||||
* not readable, they will be skipped, and the total size will be set to
|
||||
* zero.
|
||||
*
|
||||
* Returns the total size, or 0 if it is unknown.
|
||||
*/
|
||||
static off_t pv_calc_total_lines(pvstate_t state)
|
||||
{
|
||||
off_t total;
|
||||
struct stat sb;
|
||||
unsigned int file_idx;
|
||||
|
||||
total = 0;
|
||||
|
||||
for (file_idx = 0; file_idx < state->files.file_count && NULL != state->files.filename; file_idx++) {
|
||||
int fd = -1;
|
||||
int rc = 0;
|
||||
|
||||
/* Skip any NULL entries, though they should be impossible. */
|
||||
if (NULL == state->files.filename[file_idx])
|
||||
continue;
|
||||
|
||||
if (0 == strcmp(state->files.filename[file_idx], "-")) {
|
||||
rc = fstat(STDIN_FILENO, &sb);
|
||||
if ((rc != 0) || (!S_ISREG(sb.st_mode))) {
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
fd = dup(STDIN_FILENO);
|
||||
} else {
|
||||
rc = stat(state->files.filename[file_idx], &sb);
|
||||
if ((rc != 0) || (!S_ISREG(sb.st_mode))) {
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
fd = open(state->files.filename[file_idx], O_RDONLY); /* flawfinder: ignore */
|
||||
/* flawfinder - see last open() below. */
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
debug("%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
#if HAVE_POSIX_FADVISE
|
||||
/* Advise the OS that all reads will be sequential. */
|
||||
(void) posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
char scanbuf[1024]; /* flawfinder: ignore */
|
||||
ssize_t numread, buf_idx;
|
||||
|
||||
/* flawfinder - always bounded, below. */
|
||||
|
||||
numread = read(fd, scanbuf, sizeof(scanbuf)); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: every read is reading into
|
||||
* the start of the buffer, not moving along it, so
|
||||
* the bounding is OK.
|
||||
*/
|
||||
if (numread < 0) {
|
||||
pv_perror("%s", state->files.filename[file_idx]);
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
break;
|
||||
} else if (0 == numread) {
|
||||
break;
|
||||
}
|
||||
for (buf_idx = 0; buf_idx < numread; buf_idx++) {
|
||||
if (state->control.null_terminated_lines) {
|
||||
if ('\0' == scanbuf[buf_idx])
|
||||
total++;
|
||||
} else {
|
||||
if ('\n' == scanbuf[buf_idx])
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != lseek(fd, 0, SEEK_SET)) {
|
||||
pv_perror("%s", state->files.filename[file_idx]);
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Work out the total size of all data by adding up the sizes of all input
|
||||
* files, using either pv_calc_total_bytes() or pv_calc_total_lines()
|
||||
* depending on whether state->control.linemode is true.
|
||||
*
|
||||
* Returns the total size, or 0 if it is unknown.
|
||||
*/
|
||||
off_t pv_calc_total_size(pvstate_t state)
|
||||
{
|
||||
if (state->control.linemode) {
|
||||
return pv_calc_total_lines(state);
|
||||
} else {
|
||||
return pv_calc_total_bytes(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Close the given file descriptor and open the next one, whose number in
|
||||
* the list is "filenum", returning the new file descriptor (or negative on
|
||||
* error). It is an error if the next input file is the same as the file
|
||||
* stdout is pointing to.
|
||||
* the output is pointing to.
|
||||
*
|
||||
* Updates state->current_file in the process.
|
||||
* Updates state->status.current_input_file and
|
||||
* state->status.current_input_is_pipe.
|
||||
*
|
||||
* If the input is not a pipe, and state->status.output_is_pipe is false,
|
||||
* and state->control.no_splice is false, also creates a pipe and populates
|
||||
* state->transfer.intermediate_pipe[] with its file descriptors, if a pipe
|
||||
* had not already been created (i.e. that array contained [-1,-1]).
|
||||
*/
|
||||
int pv_next_file(pvstate_t state, int filenum, int oldfd)
|
||||
int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
{
|
||||
struct stat isb;
|
||||
struct stat osb;
|
||||
int fd, input_file_is_stdout;
|
||||
int fd;
|
||||
bool input_file_is_output;
|
||||
char *next_filename;
|
||||
|
||||
if (oldfd > 0) {
|
||||
if (close(oldfd)) {
|
||||
pv_error(state, "%s: %s", _("failed to close file"), strerror(errno));
|
||||
state->exit_status |= 8;
|
||||
if (oldfd >= 0) {
|
||||
if (0 != close(oldfd)) {
|
||||
pv_perror("%s: %s", pv_current_file_name(state), _("error closing file"));
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSITION;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (filenum >= state->input_file_count) {
|
||||
state->exit_status |= 8;
|
||||
if (filenum >= state->files.file_count) {
|
||||
debug("%s: %d >= %d", "filenum too large", filenum, state->files.file_count);
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSITION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (filenum < 0) {
|
||||
state->exit_status |= 8;
|
||||
return -1;
|
||||
next_filename = NULL;
|
||||
if (NULL != state->files.filename) {
|
||||
next_filename = state->files.filename[filenum];
|
||||
if (NULL == next_filename) {
|
||||
debug("%s: @%d, max %d", "unexpected null filename", filenum, state->files.file_count);
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSITION;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == strcmp(state->input_files[filenum], "-")) {
|
||||
if ((NULL == next_filename) || (0 == strcmp(next_filename, "-"))) {
|
||||
fd = STDIN_FILENO;
|
||||
} else {
|
||||
fd = open(state->input_files[filenum], O_RDONLY);
|
||||
fd = open(next_filename, O_RDONLY); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: the input file list is under the
|
||||
* control of the operator by its nature, so refusing to
|
||||
* open symlinks would be counterintuitive.
|
||||
*/
|
||||
if (fd < 0) {
|
||||
pv_error(state, "%s: %s: %s",
|
||||
_("failed to read file"), state->input_files[filenum], strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
pv_perror("%s", next_filename);
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fstat(fd, &isb)) {
|
||||
pv_error(state, "%s: %s: %s", _("failed to stat file"), state->input_files[filenum], strerror(errno));
|
||||
close(fd);
|
||||
state->exit_status |= 2;
|
||||
if (0 != fstat(fd, &isb)) {
|
||||
pv_perror("%s", NULL == next_filename ? "-" : next_filename);
|
||||
(void) close(fd);
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fstat(STDOUT_FILENO, &osb)) {
|
||||
pv_error(state, "%s: %s", _("failed to stat output file"), strerror(errno));
|
||||
close(fd);
|
||||
state->exit_status |= 2;
|
||||
if (0 != fstat(state->control.output_fd, &osb)) {
|
||||
pv_perror("%s", NULL == state->control.output_name ? "(null)" : state->control.output_name);
|
||||
(void) close(fd);
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that this new input file is not the same as stdout's
|
||||
* destination. This restriction is ignored for anything other
|
||||
* than a regular file or block device.
|
||||
* If the input file is a regular file or a block device, check that
|
||||
* it is not the same as the output's destination.
|
||||
*/
|
||||
input_file_is_stdout = 1;
|
||||
input_file_is_output = true;
|
||||
if (isb.st_dev != osb.st_dev)
|
||||
input_file_is_stdout = 0;
|
||||
input_file_is_output = false;
|
||||
if (isb.st_ino != osb.st_ino)
|
||||
input_file_is_stdout = 0;
|
||||
if (isatty(fd))
|
||||
input_file_is_stdout = 0;
|
||||
input_file_is_output = false;
|
||||
if (0 != isatty(fd))
|
||||
input_file_is_output = false;
|
||||
if ((!S_ISREG(isb.st_mode)) && (!S_ISBLK(isb.st_mode)))
|
||||
input_file_is_stdout = 0;
|
||||
input_file_is_output = false;
|
||||
|
||||
if (input_file_is_stdout) {
|
||||
pv_error(state, "%s: %s", _("input file is output file"), state->input_files[filenum]);
|
||||
close(fd);
|
||||
state->exit_status |= 4;
|
||||
if (input_file_is_output) {
|
||||
pv_error("%s: %s", NULL == next_filename ? "-" : next_filename, _("input file is also the output"));
|
||||
(void) close(fd);
|
||||
state->status.exit_status |= PV_ERROREXIT_OUROBOROS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->current_file = state->input_files[filenum];
|
||||
if (0 == strcmp(state->input_files[filenum], "-")) {
|
||||
state->current_file = "(stdin)";
|
||||
/*
|
||||
* Detect whether the input file is a pipe, a regular file, or
|
||||
* neither. This is used later, in pv__transfer_read(), when
|
||||
* determining the transfer method - read/write, splice(),
|
||||
* copy_file_range().
|
||||
*/
|
||||
state->status.current_input_is_pipe = false;
|
||||
state->status.current_input_is_file = false;
|
||||
if ((isb.st_mode & S_IFMT) == S_IFIFO) {
|
||||
state->status.current_input_is_pipe = true;
|
||||
debug("%s (fd %d)", "input is a pipe", fd);
|
||||
} else if ((isb.st_mode & S_IFMT) == S_IFREG) {
|
||||
state->status.current_input_is_file = true;
|
||||
debug("%s (fd %d)", "input is a regular file", fd);
|
||||
}
|
||||
|
||||
state->status.current_input_file = filenum;
|
||||
#ifdef O_DIRECT
|
||||
/*
|
||||
* Set or clear O_DIRECT on the file descriptor.
|
||||
*/
|
||||
fcntl(fd, F_SETFL, (state->direct_io ? O_DIRECT : 0) | fcntl(fd, F_GETFL));
|
||||
if (0 != fcntl(fd, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(fd, F_GETFL))) {
|
||||
/*@-compdef@ */
|
||||
/*
|
||||
* splint - passed or returned storage is undefined - but at
|
||||
* this point, the input file list has been populated, so
|
||||
* that's OK.
|
||||
*/
|
||||
debug("%s: %s: %s", pv_current_file_name(state), "fcntl", strerror(errno));
|
||||
/*@+compdef@ */
|
||||
}
|
||||
/*
|
||||
* We don't clear direct_io_changed here, to avoid race conditions
|
||||
* that could cause the input and output settings to differ.
|
||||
* Don't clear direct_io_changed here, to avoid race conditions that
|
||||
* could cause the input and output settings to differ.
|
||||
*/
|
||||
#endif /* O_DIRECT */
|
||||
|
||||
debug("%s: %d: %s: fd=%d, is_pipe=%s, is_file=%s", "next file opened", filenum, pv_current_file_name(state), fd,
|
||||
state->status.current_input_is_pipe ? "true" : "false",
|
||||
state->status.current_input_is_file ? "true" : "false");
|
||||
|
||||
#ifdef HAVE_SPLICE
|
||||
if (state->control.discard_input && !state->control.no_splice && state->transfer.discard_fd < 0) {
|
||||
/*
|
||||
* Open a file descriptor to /dev/null, so that input can be
|
||||
* spliced to it to implement -X.
|
||||
*
|
||||
* If this fails, transfer.discard_fd will be left at -1,
|
||||
* which means the transfer functions will not use splice().
|
||||
*/
|
||||
state->transfer.discard_fd = open("/dev/null", O_WRONLY); /* flawfinder: ignore */
|
||||
/* flawfinder: /dev/null is trusted. */
|
||||
if (state->transfer.discard_fd < 0) {
|
||||
debug("%s: %s", "/dev/null", strerror(errno));
|
||||
state->transfer.discard_fd = -1;
|
||||
}
|
||||
if (!pv_fd_is_dev_null(state->transfer.discard_fd, false)) {
|
||||
if (state->transfer.discard_fd >= 0)
|
||||
(void) close(state->transfer.discard_fd);
|
||||
state->transfer.discard_fd = -1;
|
||||
}
|
||||
debug("%s: %d", "discard_fd", state->transfer.discard_fd);
|
||||
/*
|
||||
* If discard_fd was successfully opened, it will be used as
|
||||
* the output, so set the output status flags appropriately.
|
||||
*/
|
||||
if (state->transfer.discard_fd >= 0) {
|
||||
state->status.output_is_pipe = false;
|
||||
state->status.output_is_file = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(state->status.output_is_pipe || state->status.current_input_is_pipe || state->control.no_splice)
|
||||
&& (-1 == state->transfer.intermediate_pipe[0])) {
|
||||
/*
|
||||
* Create an intermediate pipe to allow the input to be used
|
||||
* with splice() even though neither it nor the output are
|
||||
* themselves pipes.
|
||||
*/
|
||||
state->transfer.intermediate_pipe_buffer_used = 0;
|
||||
if (pipe(state->transfer.intermediate_pipe) < 0) {
|
||||
debug("%s: %s", "pipe()", strerror(errno));
|
||||
state->transfer.intermediate_pipe[0] = -1;
|
||||
state->transfer.intermediate_pipe[1] = -1;
|
||||
} else {
|
||||
state->transfer.intermediate_pipe_buffer_size = 64 * 1024;
|
||||
#if defined F_SETPIPE_SZ && defined F_GETPIPE_SZ
|
||||
{
|
||||
size_t target_pipe_buffer_size = state->control.pipe_buffer_size;
|
||||
int new_size;
|
||||
|
||||
/* If no pipe buffer size was set, try for 1MiB. */
|
||||
if (0 == target_pipe_buffer_size)
|
||||
target_pipe_buffer_size = 1024 * 1024;
|
||||
|
||||
/*
|
||||
* Try to set the pipe buffer size, halving
|
||||
* repeatedly on failure.
|
||||
*/
|
||||
new_size = -1;
|
||||
while (new_size < 0 && target_pipe_buffer_size >= 4096) {
|
||||
new_size =
|
||||
fcntl(state->transfer.intermediate_pipe[1], F_SETPIPE_SZ,
|
||||
(int) target_pipe_buffer_size);
|
||||
if (new_size < 0)
|
||||
target_pipe_buffer_size = target_pipe_buffer_size / 2;
|
||||
}
|
||||
/* If all attempts failed, read the current size. */
|
||||
if (new_size < 0) {
|
||||
new_size = fcntl(state->transfer.intermediate_pipe[1], F_GETPIPE_SZ);
|
||||
/* If unable to read, assume 64KiB. */
|
||||
if (new_size < 0) {
|
||||
new_size = 64 * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
state->transfer.intermediate_pipe_buffer_size = new_size;
|
||||
}
|
||||
#endif /* defined F_SETPIPE_SZ && defined F_GETPIPE_SZ */
|
||||
}
|
||||
debug("%s: [%d,%d]", "intermediate pipe fds", state->transfer.intermediate_pipe[0],
|
||||
state->transfer.intermediate_pipe[1]);
|
||||
debug("%s: %d", "intermediate pipe buffer size", state->transfer.intermediate_pipe_buffer_size);
|
||||
}
|
||||
#endif /* HAVE_SPLICE */
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
/*
|
||||
* Return the name of the current file. The returned buffer may point to
|
||||
* internal state and must not be passed to free() or used after "state" is
|
||||
* freed.
|
||||
*/
|
||||
/*@keep@*/ const char *pv_current_file_name(pvstate_t state)
|
||||
{
|
||||
static char *str_none = NULL;
|
||||
static char *str_stdin = NULL;
|
||||
const char *input_file_name = NULL;
|
||||
|
||||
/*@-observertrans@ */
|
||||
/*@-onlytrans@ */
|
||||
/*@-statictrans@ */
|
||||
/*
|
||||
* The returned string could be an allocated string from the
|
||||
* state->files.filename array, a constant string, or a returned
|
||||
* string from gettext(). The documentation, above, explains that
|
||||
* the returned string expires with the state.
|
||||
*/
|
||||
|
||||
if (NULL == str_none)
|
||||
str_none = _("(none)");
|
||||
if (NULL == str_stdin)
|
||||
str_stdin = _("(stdin)");
|
||||
|
||||
/* Fallback in case of translation failure. */
|
||||
if (NULL == str_none)
|
||||
str_none = "(none)";
|
||||
if (NULL == str_stdin)
|
||||
str_stdin = "(stdin)";
|
||||
|
||||
if (state->status.current_input_file < 0)
|
||||
return str_none;
|
||||
if ((unsigned int) (state->status.current_input_file) >= state->files.file_count)
|
||||
return str_none;
|
||||
|
||||
if (NULL == state->files.filename) {
|
||||
input_file_name = NULL;
|
||||
} else {
|
||||
input_file_name = state->files.filename[state->status.current_input_file];
|
||||
}
|
||||
if (NULL == input_file_name)
|
||||
return str_none;
|
||||
if (0 == strcmp(input_file_name, "-"))
|
||||
return str_stdin;
|
||||
|
||||
/*@-compdef@ */
|
||||
return input_file_name;
|
||||
/*@+compdef@ */
|
||||
/*
|
||||
* splint warns about state->files.filename being undefined, but it
|
||||
* has definitely been fully populated by the time this function is
|
||||
* called.
|
||||
*/
|
||||
|
||||
/*@+statictrans@ */
|
||||
/*@+onlytrans@ */
|
||||
/*@+observertrans@ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a stream pointer, and populate the filename buffer, for a control
|
||||
* file associated with a particular process ID, for the given signal
|
||||
* number; it will be opened for writing if "sender" is true. Returns NULL
|
||||
* on error.
|
||||
*/
|
||||
/*@null@ */
|
||||
/*@dependent@ */
|
||||
FILE *pv_open_controlfile(char *filename, size_t bufsize, pid_t control_pid, int signum, bool sender)
|
||||
{
|
||||
int open_flags, open_mode, control_fd;
|
||||
/*@dependent@ */ FILE *control_fptr = NULL;
|
||||
|
||||
open_flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
open_flags += O_NOFOLLOW;
|
||||
#endif
|
||||
if (sender)
|
||||
open_flags = O_WRONLY | O_CREAT | O_EXCL;
|
||||
|
||||
open_mode = 0644;
|
||||
|
||||
(void) pv_snprintf(filename, bufsize, "/run/user/%lu/pv.remote.%d.%lu", (unsigned long) geteuid(), signum,
|
||||
(unsigned long) control_pid);
|
||||
control_fd = open(filename, open_flags, open_mode); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* If /run/user/<uid> wasn't usable, try $HOME/.pv instead.
|
||||
*/
|
||||
if (control_fd < 0) {
|
||||
char *home_dir;
|
||||
|
||||
home_dir = getenv("HOME"); /* flawfinder: ignore */
|
||||
if (NULL == home_dir)
|
||||
return NULL;
|
||||
if ('\0' == home_dir[0])
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* flawfinder rationale: null and zero-size values are
|
||||
* rejected, and the destination buffer is bounded.
|
||||
*/
|
||||
|
||||
(void) pv_snprintf(filename, bufsize, "%s/.pv/remote.%d.%lu", home_dir, signum,
|
||||
(unsigned long) control_pid);
|
||||
control_fd = open(filename, open_flags, open_mode); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* If the open failed, try creating the $HOME/.pv directory
|
||||
* first.
|
||||
*/
|
||||
if (control_fd < 0) {
|
||||
(void) pv_snprintf(filename, bufsize, "%s/.pv", home_dir);
|
||||
(void) mkdir(filename, 0700);
|
||||
/* In case of weird umask, explicitly chmod the dir. */
|
||||
(void) chmod(filename, 0700); /* flawfinder: ignore */
|
||||
(void) pv_snprintf(filename, bufsize, "%s/.pv/remote.%d.%lu", home_dir, signum,
|
||||
(unsigned long) control_pid);
|
||||
control_fd = open(filename, open_flags, open_mode); /* flawfinder: ignore */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* flawfinder rationale: the files are in a directory whose parents
|
||||
* cannot be manipulated, and the final component is not allowed to
|
||||
* be a symbolic link. $HOME is checked for a NULL value, and the
|
||||
* filename is bounded by pv_snprintf() so it can't overshoot the
|
||||
* filename buffer. When chmod() is called on $HOME/.pv, an
|
||||
* attacker is assumed to be unlikely to be able to manipulate
|
||||
* $HOME's contents to make use of $HOME/.pv's mode of 700.
|
||||
*/
|
||||
|
||||
if (control_fd < 0)
|
||||
return NULL;
|
||||
|
||||
debug("%s: %s", "control filename", filename);
|
||||
|
||||
control_fptr = fdopen(control_fd, sender ? "wb" : "rb");
|
||||
|
||||
return control_fptr;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Formatter function for average rate.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Average transfer rate.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_average_rate(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore - always bounded */
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
/*@-mustfreefresh@ */
|
||||
if (args->control->numeric) {
|
||||
/* Numeric - raw value without suffix. */
|
||||
(void) pv_snprintf(content, sizeof(content),
|
||||
"%.4Lf", ((args->control->bits ? 8.0 : 1.0) * args->calc->average_rate));
|
||||
} else if (args->control->bits && !args->control->linemode) {
|
||||
/* Bits per second. */
|
||||
pv_describe_amount(content, sizeof(content),
|
||||
"(%s)", 8 * args->calc->average_rate, "", _("b/s"), args->display->count_type);
|
||||
} else {
|
||||
/* Bytes or lines per second. */
|
||||
pv_describe_amount(content,
|
||||
sizeof(content), "(%s)", args->calc->average_rate, _("/s"), _("B/s"),
|
||||
args->display->count_type);
|
||||
}
|
||||
/*@+mustfreefresh@ *//* splint - false positive from gettext(). */
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Formatter functions for styled progress bars.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#if defined(ENABLE_NLS) && defined(HAVE_WCHAR_H)
|
||||
#include <wchar.h>
|
||||
#if defined(HAVE_WCTYPE_H)
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Populate "style" with the named bar style, falling back to plain if the
|
||||
* name was not recognised. Returns true if the named style was found.
|
||||
*
|
||||
* Note that strings are copied into the structure, rather than just
|
||||
* updating pointers, to maintain separation of concern between different
|
||||
* parts of the code - and because on 64-bit architectures, the sizes of the
|
||||
* data types and their associated alignment padding tend to outweigh the
|
||||
* memory savings from using pointers and shared strings.
|
||||
*/
|
||||
static bool pv_barstyle(pvformatter_args_t args, pvbarstyle_t style, const char *name)
|
||||
{
|
||||
#define populate_string(item, str, w) { \
|
||||
item.width = w; \
|
||||
item.bytes = strlen(str); /* flawfinder: ignore */ \
|
||||
if (item.bytes > 0 && item.bytes <= PV_BARSTYLE_SIZEOF_STRING) \
|
||||
memcpy(item.string, str, item.bytes); /* flawfinder: ignore */ \
|
||||
}
|
||||
/*
|
||||
* flawfinder - strlen() on null-terminated static strings is OK,
|
||||
* and with the memcpy(), the buffer size has been checked.
|
||||
*/
|
||||
|
||||
memset(style, 0, sizeof(*style));
|
||||
|
||||
if (args->status->terminal_supports_utf8 && 0 == strcmp(name, "block")) {
|
||||
|
||||
style->style_id = 2;
|
||||
|
||||
populate_string(style->indicator, "◀▶", 2);
|
||||
populate_string(style->tip, "", 0);
|
||||
|
||||
populate_string(style->filler[0], " ", 1);
|
||||
populate_string(style->filler[1], "█", 1);
|
||||
|
||||
style->filler_entries = 2;
|
||||
|
||||
return true;
|
||||
|
||||
} else if (args->status->terminal_supports_utf8 && 0 == strcmp(name, "granular")) {
|
||||
|
||||
style->style_id = 3;
|
||||
|
||||
populate_string(style->indicator, "◀▶", 2);
|
||||
populate_string(style->tip, "", 0);
|
||||
|
||||
populate_string(style->filler[0], " ", 1);
|
||||
populate_string(style->filler[1], "▏", 1);
|
||||
populate_string(style->filler[2], "▎", 1);
|
||||
populate_string(style->filler[3], "▍", 1);
|
||||
populate_string(style->filler[4], "▌", 1);
|
||||
populate_string(style->filler[5], "▋", 1);
|
||||
populate_string(style->filler[6], "▊", 1);
|
||||
populate_string(style->filler[7], "▉", 1);
|
||||
populate_string(style->filler[8], "█", 1);
|
||||
|
||||
style->filler_entries = 9;
|
||||
|
||||
return true;
|
||||
|
||||
} else if (args->status->terminal_supports_utf8 && 0 == strcmp(name, "shaded")) {
|
||||
|
||||
style->style_id = 4;
|
||||
|
||||
populate_string(style->indicator, "▒▓▒", 3);
|
||||
populate_string(style->tip, "", 0);
|
||||
|
||||
populate_string(style->filler[0], "░", 1);
|
||||
populate_string(style->filler[1], "▒", 1);
|
||||
populate_string(style->filler[2], "▓", 1);
|
||||
populate_string(style->filler[3], "█", 1);
|
||||
|
||||
style->filler_entries = 4;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Default plain style. */
|
||||
|
||||
style->style_id = 1;
|
||||
|
||||
populate_string(style->indicator, "<=>", 3);
|
||||
populate_string(style->tip, ">", 1);
|
||||
|
||||
populate_string(style->filler[0], " ", 1);
|
||||
populate_string(style->filler[1], "=", 1);
|
||||
|
||||
style->filler_entries = 2;
|
||||
|
||||
if (0 == strcmp(name, "plain"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the index into args->display->barstyle for the style with the
|
||||
* given name, adding that style to the array if it's not there already and
|
||||
* there's room.
|
||||
*
|
||||
* If there is no room, returns zero, so the first style is re-used.
|
||||
*/
|
||||
int8_t pv_display_barstyle_index(pvformatter_args_t args, const char *name)
|
||||
{
|
||||
struct pvbarstyle_s style;
|
||||
int8_t barstyle_index;
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
bool found;
|
||||
#endif
|
||||
|
||||
memset(&style, 0, sizeof(style));
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
found = pv_barstyle(args, &style, name);
|
||||
if (!found)
|
||||
debug("%s: %s", name, "bar style not found, using plain");
|
||||
#else
|
||||
(void) pv_barstyle(args, &style, name);
|
||||
#endif
|
||||
|
||||
for (barstyle_index = 0;
|
||||
barstyle_index < PV_BARSTYLE_MAX && args->display->barstyle[barstyle_index].style_id > 0;
|
||||
barstyle_index++) {
|
||||
if (args->display->barstyle[barstyle_index].style_id == style.style_id) {
|
||||
debug("%s: %s: %d", name, "found in bar style array", barstyle_index);
|
||||
return barstyle_index;
|
||||
}
|
||||
}
|
||||
|
||||
if (barstyle_index >= PV_BARSTYLE_MAX) {
|
||||
debug("%s: %s", name, "no room to add another bar style - returning 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&(args->display->barstyle[barstyle_index]), &style, sizeof(style)); /* flawfinder: ignore */
|
||||
/* flawfinder - the destination is an array element of the right size. */
|
||||
debug("%s: %s: %d", name, "added to bar style array", barstyle_index);
|
||||
return barstyle_index;
|
||||
}
|
||||
|
||||
|
||||
pvdisplay_bytecount_t pv_formatter_bar_default(pvformatter_args_t args)
|
||||
{
|
||||
if (0 == args->segment->parameter) {
|
||||
const char *default_name;
|
||||
default_name = args->control->default_bar_style;
|
||||
/*@-branchstate@ */
|
||||
if (NULL == default_name)
|
||||
default_name = "plain";
|
||||
/*@+branchstate@ */
|
||||
/* splint - it doesn't matter that default_name may be static. */
|
||||
args->segment->parameter = 1 + pv_display_barstyle_index(args, default_name);
|
||||
}
|
||||
return pv_formatter_progress_bar_only(args);
|
||||
}
|
||||
|
||||
pvdisplay_bytecount_t pv_formatter_bar_plain(pvformatter_args_t args)
|
||||
{
|
||||
if (0 == args->segment->parameter)
|
||||
args->segment->parameter = 1 + pv_display_barstyle_index(args, "plain");
|
||||
return pv_formatter_progress_bar_only(args);
|
||||
}
|
||||
|
||||
pvdisplay_bytecount_t pv_formatter_bar_block(pvformatter_args_t args)
|
||||
{
|
||||
if (0 == args->segment->parameter)
|
||||
args->segment->parameter = 1 + pv_display_barstyle_index(args, "block");
|
||||
return pv_formatter_progress_bar_only(args);
|
||||
}
|
||||
|
||||
pvdisplay_bytecount_t pv_formatter_bar_granular(pvformatter_args_t args)
|
||||
{
|
||||
if (0 == args->segment->parameter)
|
||||
args->segment->parameter = 1 + pv_display_barstyle_index(args, "granular");
|
||||
return pv_formatter_progress_bar_only(args);
|
||||
}
|
||||
|
||||
pvdisplay_bytecount_t pv_formatter_bar_shaded(pvformatter_args_t args)
|
||||
{
|
||||
if (0 == args->segment->parameter)
|
||||
args->segment->parameter = 1 + pv_display_barstyle_index(args, "shaded");
|
||||
return pv_formatter_progress_bar_only(args);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Formatter function for transfer buffer percentage utilisation.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Percentage transfer buffer utilisation.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_buffer_percent(pvformatter_args_t args)
|
||||
{
|
||||
char content[16]; /* flawfinder: ignore - always bounded */
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
if (args->transfer->buffer_size > 0) {
|
||||
double pct_used = pv_percentage((off_t)
|
||||
(args->transfer->read_position - args->transfer->write_position),
|
||||
(off_t)
|
||||
(args->transfer->buffer_size));
|
||||
(void) pv_snprintf(content, sizeof(content), "{%3.0f%%}", pct_used);
|
||||
}
|
||||
switch (args->transfer->method) {
|
||||
case PV_TRANSFERMETHOD_READWRITE:
|
||||
break;
|
||||
case PV_TRANSFERMETHOD_SPLICE:
|
||||
(void) pv_snprintf(content, sizeof(content), "{%s}", "----");
|
||||
break;
|
||||
case PV_TRANSFERMETHOD_SPLICE_INTERMEDIATE:
|
||||
(void) pv_snprintf(content, sizeof(content), "{%s}", "-||-");
|
||||
break;
|
||||
case PV_TRANSFERMETHOD_COPY_FILE_RANGE:
|
||||
(void) pv_snprintf(content, sizeof(content), "{%s}", "--->");
|
||||
break;
|
||||
case PV_TRANSFERMETHOD__UNSET:
|
||||
(void) pv_snprintf(content, sizeof(content), "{%s}", "????");
|
||||
break;
|
||||
}
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Formatter function for bytes or lines transferred.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Number of bytes or lines transferred.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_bytes(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore - always bounded */
|
||||
|
||||
args->display->showing_bytes = true;
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
/*@-mustfreefresh@ */
|
||||
if (args->control->numeric) {
|
||||
/* Numeric mode - raw values only, no suffix. */
|
||||
(void) pv_snprintf(content, sizeof(content),
|
||||
"%lld", (long long) ((args->control->bits ? 8 : 1) * args->transfer->transferred));
|
||||
} else if (args->control->bits && !args->control->linemode) {
|
||||
pv_describe_amount(content, sizeof(content), "%s",
|
||||
(long double) (args->transfer->transferred * 8), "", _("b"),
|
||||
args->display->count_type);
|
||||
} else {
|
||||
pv_describe_amount(content, sizeof(content), "%s",
|
||||
(long double) (args->transfer->transferred), "", _("B"), args->display->count_type);
|
||||
}
|
||||
/*@+mustfreefresh@ *//* splint - false positive from gettext(). */
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Formatter function for OSC 9;4 - ConEmu progress bar - codes.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Populate a buffer with OSC 9;4 progress bar codes for terminal title
|
||||
* tabs, returning the length of the string.
|
||||
*/
|
||||
size_t pv_osc94_format(char *buffer, size_t bufsize, readonly_pvcontrol_t control, readonly_pvtransfercalc_t calc)
|
||||
{
|
||||
int formatted_size = 0;
|
||||
|
||||
if (NULL == buffer)
|
||||
return 0;
|
||||
if (bufsize < 1)
|
||||
return 0;
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (control->size > 0 || control->rate_gauge) {
|
||||
/* Known size or rate gauge - percentage progress. */
|
||||
formatted_size = pv_snprintf(buffer, bufsize, "\033]9;4;1;%.0f\033\\", calc->percentage);
|
||||
} else {
|
||||
/* Unknown size - indeterminate progress. */
|
||||
/* See pv_formatter_progress_unknownsize() in progressbar.c. */
|
||||
double indicator_position;
|
||||
|
||||
indicator_position = calc->percentage;
|
||||
if (indicator_position > 200.0)
|
||||
#if HAVE_FMOD
|
||||
indicator_position = fmod(indicator_position, 200.0);
|
||||
#else
|
||||
{
|
||||
while (indicator_position > 200.0)
|
||||
indicator_position -= 200.0;
|
||||
}
|
||||
#endif
|
||||
if (indicator_position > 100.0) {
|
||||
indicator_position = 200.0 - indicator_position;
|
||||
}
|
||||
if (indicator_position < 0.0) {
|
||||
indicator_position = 0.0;
|
||||
}
|
||||
|
||||
formatted_size = pv_snprintf(buffer, bufsize, "\033]9;4;3;%.0f\033\\", indicator_position);
|
||||
}
|
||||
|
||||
if (formatted_size < 0)
|
||||
return 0;
|
||||
if (formatted_size >= (int) bufsize)
|
||||
return bufsize - 1;
|
||||
return (size_t) formatted_size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Produce OSC 9;4 progress bar codes for terminal title tabs.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_progress_conemu(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore */
|
||||
|
||||
/* flawfinder - null-terminated and bounded with pv_snprintf(). */
|
||||
|
||||
memset(content, 0, sizeof(content));
|
||||
|
||||
(void) pv_osc94_format(content, sizeof(content), args->control, args->calc);
|
||||
|
||||
args->display->using_osc94 = true;
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Formatter function for ETA display.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
/*
|
||||
* Estimated time until completion.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_eta(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore - bounded in pv_snprintf(). */
|
||||
long eta, max_days;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
/*
|
||||
* Don't try to calculate this if the size is not known.
|
||||
*/
|
||||
if (args->control->size < 1)
|
||||
return 0;
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
eta =
|
||||
pv_seconds_remaining((args->transfer->transferred - args->display->initial_offset),
|
||||
args->control->size - args->display->initial_offset, args->calc->current_avg_rate);
|
||||
|
||||
/* The ETA must always be positive. */
|
||||
if (eta < 0)
|
||||
eta = 0;
|
||||
|
||||
/* The ETA must be under 1,000,000 days so it's not too wide. */
|
||||
/* If a "long" is 32 bits, only 24,855 days will fit in it. */
|
||||
max_days = 24855L;
|
||||
#ifdef LONG_MAX
|
||||
if (LONG_MAX > 2147483647L)
|
||||
max_days = 1000000;
|
||||
#endif
|
||||
|
||||
if ((eta / 86400L) >= max_days)
|
||||
eta = max_days * 86400L - 1L;
|
||||
|
||||
/*
|
||||
* If the ETA is more than a day, include a day count as well as
|
||||
* hours, minutes, and seconds.
|
||||
*/
|
||||
/*@-mustfreefresh@ */
|
||||
if (eta > 86400L) {
|
||||
(void) pv_snprintf(content,
|
||||
sizeof(content),
|
||||
"%.16s %ld:%02ld:%02ld:%02ld",
|
||||
_("ETA"), eta / 86400, (eta / 3600) % 24, (eta / 60) % 60, eta % 60);
|
||||
} else {
|
||||
(void) pv_snprintf(content,
|
||||
sizeof(content),
|
||||
"%.16s %ld:%02ld:%02ld", _("ETA"), eta / 3600, (eta / 60) % 60, eta % 60);
|
||||
}
|
||||
/*@+mustfreefresh@ *//* splint: false positives from gettext(). */
|
||||
|
||||
/*
|
||||
* If this is the final update, show a blank space where the ETA
|
||||
* used to be.
|
||||
*/
|
||||
if (args->display->final_update) {
|
||||
size_t erase_idx;
|
||||
for (erase_idx = 0; erase_idx < sizeof(content) && content[erase_idx] != '\0'; erase_idx++) {
|
||||
content[erase_idx] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Formatter function for the local time at which the transfer is expected
|
||||
* to complete.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
/*
|
||||
* Estimated local time of completion.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_fineta(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore - bounded by strftime(). */
|
||||
time_t now, then;
|
||||
const struct tm *time_ptr;
|
||||
long eta, max_years;
|
||||
const char *time_format;
|
||||
bool show_fineta;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
/*
|
||||
* Don't try to calculate this if the size is not known.
|
||||
*/
|
||||
if (args->control->size < 1)
|
||||
return 0;
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
now = time(NULL);
|
||||
show_fineta = true;
|
||||
time_format = NULL;
|
||||
|
||||
/*
|
||||
* Note that the completion clock time may be hidden by a failed
|
||||
* localtime lookup.
|
||||
*/
|
||||
|
||||
eta = pv_seconds_remaining(args->transfer->transferred - args->display->initial_offset,
|
||||
args->control->size - args->display->initial_offset, args->calc->current_avg_rate);
|
||||
|
||||
/* The ETA must always be positive. */
|
||||
if (eta < 0)
|
||||
eta = 0;
|
||||
|
||||
/* Clamp the ETA to 7,000 years max so the date isn't too wide. */
|
||||
/* If a "long" is 32 bits, only 68 years will fit in it. */
|
||||
max_years = 68;
|
||||
#ifdef LONG_MAX
|
||||
if (LONG_MAX > 2147483647L)
|
||||
max_years = 7000;
|
||||
#endif
|
||||
|
||||
if ((eta / 31536000L) > max_years)
|
||||
eta = 31536000L * max_years;
|
||||
|
||||
/*
|
||||
* Only include the date if the ETA is more than 6 hours
|
||||
* away.
|
||||
*/
|
||||
if (eta > (long) (6 * 3600)) {
|
||||
time_format = "%Y-%m-%d %H:%M:%S";
|
||||
} else {
|
||||
time_format = "%H:%M:%S";
|
||||
}
|
||||
|
||||
then = now + eta;
|
||||
time_ptr = localtime(&then);
|
||||
|
||||
if (NULL == time_ptr) {
|
||||
show_fineta = false;
|
||||
} else {
|
||||
/*
|
||||
* The localtime() function keeps data stored in a static
|
||||
* buffer that gets overwritten by time functions.
|
||||
*/
|
||||
struct tm time = *time_ptr;
|
||||
size_t content_bytes;
|
||||
|
||||
/*@-mustfreefresh@ */
|
||||
(void) pv_snprintf(content, sizeof(content), "%.16s ", _("FIN"));
|
||||
/*@+mustfreefresh@ *//* splint: false positive from gettext(). */
|
||||
content_bytes = strlen(content); /* flawfinder: ignore */
|
||||
/* flawfinder: always bounded with \0 by pv_snprintf(). */
|
||||
(void) strftime(content + content_bytes, sizeof(content) - 1 - content_bytes, time_format, &time);
|
||||
}
|
||||
|
||||
if (!show_fineta) {
|
||||
size_t erase_idx;
|
||||
for (erase_idx = 0; erase_idx < sizeof(content) && content[erase_idx] != '\0'; erase_idx++) {
|
||||
content[erase_idx] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Formatter function for showing the last bytes written.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Display the last few bytes written.
|
||||
*
|
||||
* As a side effect, this sets args->display->lastwritten_bytes to
|
||||
* the segment's chosen_size, if it was previously smaller than that.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_last_written(pvformatter_args_t args)
|
||||
{
|
||||
pvdisplay_bytecount_t bytes_to_show, read_offset, write_offset, remaining;
|
||||
|
||||
args->display->showing_last_written = true;
|
||||
|
||||
bytes_to_show = args->segment->chosen_size;
|
||||
if (0 == bytes_to_show)
|
||||
bytes_to_show = args->segment->width;
|
||||
if (0 == bytes_to_show)
|
||||
return 0;
|
||||
|
||||
if (bytes_to_show > PV_SIZEOF_LASTWRITTEN_BUFFER)
|
||||
bytes_to_show = PV_SIZEOF_LASTWRITTEN_BUFFER;
|
||||
if (bytes_to_show > args->display->lastwritten_bytes)
|
||||
args->display->lastwritten_bytes = bytes_to_show;
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
if (args->offset + bytes_to_show >= args->buffer_size)
|
||||
return 0;
|
||||
|
||||
args->segment->offset = args->offset;
|
||||
args->segment->bytes = bytes_to_show;
|
||||
|
||||
read_offset = args->display->lastwritten_bytes - bytes_to_show;
|
||||
write_offset = args->offset;
|
||||
for (remaining = bytes_to_show; remaining > 0; remaining--) {
|
||||
char display_char = args->display->lastwritten_buffer[read_offset++];
|
||||
args->buffer[write_offset++] = pv_isprint(display_char) ? display_char : '.';
|
||||
}
|
||||
|
||||
return bytes_to_show;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Formatter function for showing the name of the transfer.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* Display the transfer's name.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_name(pvformatter_args_t args)
|
||||
{
|
||||
char string_format[32]; /* flawfinder: ignore - always bounded */
|
||||
char content[512]; /* flawfinder: ignore - always bounded */
|
||||
pvdisplay_bytecount_t field_width;
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
field_width = args->segment->chosen_size;
|
||||
if (field_width < 1)
|
||||
field_width = 9;
|
||||
if (field_width > 500)
|
||||
field_width = 500;
|
||||
|
||||
memset(string_format, 0, sizeof(string_format));
|
||||
(void) pv_snprintf(string_format, sizeof(string_format), "%%%d.500s:", field_width);
|
||||
|
||||
content[0] = '\0';
|
||||
if (NULL != args->control->name) {
|
||||
(void) pv_snprintf(content, sizeof(content), string_format, args->control->name);
|
||||
}
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Formatter function for the most recently written line.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Display the previously written line.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_previous_line(pvformatter_args_t args)
|
||||
{
|
||||
pvdisplay_bytecount_t bytes_to_show, read_offset, write_offset, remaining;
|
||||
|
||||
args->display->showing_previous_line = true;
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
bytes_to_show = args->segment->chosen_size;
|
||||
if (0 == bytes_to_show)
|
||||
bytes_to_show = args->segment->width;
|
||||
if (0 == bytes_to_show)
|
||||
return 0;
|
||||
|
||||
if (bytes_to_show > PV_SIZEOF_PREVLINE_BUFFER)
|
||||
bytes_to_show = PV_SIZEOF_PREVLINE_BUFFER;
|
||||
|
||||
if (args->offset + bytes_to_show >= args->buffer_size)
|
||||
return 0;
|
||||
|
||||
args->segment->offset = args->offset;
|
||||
args->segment->bytes = bytes_to_show;
|
||||
|
||||
read_offset = 0;
|
||||
write_offset = args->offset;
|
||||
for (remaining = bytes_to_show; remaining > 0; remaining--) {
|
||||
char display_char = args->display->previous_line[read_offset++];
|
||||
args->buffer[write_offset++] = pv_isprint(display_char) ? display_char : ' ';
|
||||
}
|
||||
|
||||
return bytes_to_show;
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Formatter functions for progress bars.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
/* Convenience macro for appending a string to the buffer. */
|
||||
#define append_to_buffer(x) { \
|
||||
if (buffer_offset < (buffer_size - x.bytes)) { \
|
||||
memcpy(&(buffer[buffer_offset]), x.string, x.bytes); /* flawfinder: ignore */ \
|
||||
buffer_offset += x.bytes; \
|
||||
} \
|
||||
}
|
||||
/*
|
||||
* flawfinder - the byte count and offset are checked against the buffer
|
||||
* size before memcpy() is called.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Write a progress bar to a buffer, in known-size or rate-gauge mode - a
|
||||
* bar, and a percentage (size) or max rate (gauge). The total width of the
|
||||
* content is bounded to the given width. Returns the number of bytes
|
||||
* written to the buffer.
|
||||
*
|
||||
* If "bar_sides" is false, only the bar itself is rendered, not the opening
|
||||
* and closing characters.
|
||||
*
|
||||
* If "include_bar" is false, the bar is omitted entirely.
|
||||
*
|
||||
* If "include_amount" is false, the percentage or rate after the bar is
|
||||
* omitted.
|
||||
*
|
||||
* This is only called by pv_formatter_progress().
|
||||
*/
|
||||
static pvdisplay_bytecount_t pv_formatter_progress_knownsize(pvformatter_args_t args, char *buffer,
|
||||
pvdisplay_bytecount_t buffer_size, bool bar_sides,
|
||||
bool include_bar, bool include_amount)
|
||||
{
|
||||
char after_bar[32]; /* flawfinder: ignore - only populated by pv_snprintf(). */
|
||||
pvdisplay_bytecount_t after_bar_bytes, buffer_offset;
|
||||
pvdisplay_width_t after_bar_width;
|
||||
pvdisplay_width_t bar_area_width, filled_bar_width, pad_count;
|
||||
double bar_percentage;
|
||||
pvbarstyle_t style;
|
||||
pvdisplay_bytecount_t full_cell_index;
|
||||
bool has_tip = false;
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (args->segment->parameter > 0 && args->segment->parameter <= PV_BARSTYLE_MAX) {
|
||||
style = &(args->display->barstyle[args->segment->parameter - 1]);
|
||||
} else {
|
||||
style = &(args->display->barstyle[0]);
|
||||
}
|
||||
|
||||
full_cell_index = style->filler_entries;
|
||||
if (full_cell_index > 0)
|
||||
full_cell_index--;
|
||||
if (1 == full_cell_index && style->tip.width > 0)
|
||||
has_tip = true;
|
||||
|
||||
memset(after_bar, 0, sizeof(after_bar));
|
||||
|
||||
if (args->control->size > 0) {
|
||||
/* Percentage of data transferred. */
|
||||
bar_percentage = (double) (args->calc->percentage);
|
||||
(void) pv_snprintf(after_bar, sizeof(after_bar), " %3ld%%", (int) bar_percentage);
|
||||
} else {
|
||||
/* Current rate vs max rate. */
|
||||
bar_percentage = 0.0;
|
||||
if (args->calc->rate_max > 0) {
|
||||
bar_percentage = (double) (100.0 * args->calc->transfer_rate / args->calc->rate_max);
|
||||
}
|
||||
|
||||
/*@-mustfreefresh@ */
|
||||
if (args->control->bits && !args->control->linemode) {
|
||||
/* Bits per second. */
|
||||
pv_describe_amount(after_bar, sizeof(after_bar), "/%s",
|
||||
8.0 * args->calc->rate_max, "", _("b/s"), args->display->count_type);
|
||||
} else {
|
||||
/* Bytes or lines per second. */
|
||||
pv_describe_amount(after_bar, sizeof(after_bar),
|
||||
"/%s", args->calc->rate_max, _("/s"), _("B/s"), args->display->count_type);
|
||||
}
|
||||
/*@+mustfreefresh@ *//* splint: false positives from gettext(). */
|
||||
}
|
||||
|
||||
if (!include_amount)
|
||||
after_bar[0] = '\0';
|
||||
|
||||
after_bar_bytes = strlen(after_bar); /* flawfinder: ignore */
|
||||
/* flawfinder: always \0-terminated by pv_snprintf() and the earlier memset(). */
|
||||
after_bar_width = pv_strwidth(after_bar, after_bar_bytes);
|
||||
|
||||
if (!include_bar) {
|
||||
/*
|
||||
* Only returning the "after bar" portion - the amount
|
||||
* (progress or max rate).
|
||||
*/
|
||||
if (buffer_size < after_bar_bytes)
|
||||
return 0;
|
||||
if (after_bar_bytes > 1) {
|
||||
/* NB skip the leading space. */
|
||||
memmove(buffer, after_bar + 1, after_bar_bytes - 1);
|
||||
buffer[after_bar_bytes - 1] = '\0';
|
||||
return after_bar_bytes - 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bar_sides) {
|
||||
if (args->segment->width < (after_bar_width + 2))
|
||||
return 0;
|
||||
bar_area_width = args->segment->width - after_bar_width - 2;
|
||||
} else {
|
||||
if (args->segment->width < after_bar_width)
|
||||
return 0;
|
||||
bar_area_width = args->segment->width - after_bar_width;
|
||||
}
|
||||
|
||||
filled_bar_width = (pvdisplay_width_t) ((bar_area_width * bar_percentage) / 100);
|
||||
/* Leave room for the tip of the bar. */
|
||||
if (has_tip && filled_bar_width > 0)
|
||||
filled_bar_width -= style->tip.width;
|
||||
|
||||
debug("percentage=%.2f width=%d bar_area_width=%d filled_bar_width=%d after_bar_width=%d", bar_percentage,
|
||||
args->segment->width, bar_area_width, filled_bar_width, after_bar_width);
|
||||
|
||||
buffer_offset = 0;
|
||||
|
||||
if (bar_sides) {
|
||||
/* The opening of the bar area. */
|
||||
buffer[buffer_offset++] = '[';
|
||||
}
|
||||
|
||||
/* The bar portion. */
|
||||
pad_count = 0;
|
||||
while (pad_count < filled_bar_width && pad_count < bar_area_width) {
|
||||
append_to_buffer(style->filler[full_cell_index]);
|
||||
pad_count += style->filler[full_cell_index].width;
|
||||
if (0 == style->filler[full_cell_index].width)
|
||||
pad_count++;
|
||||
}
|
||||
|
||||
/* The tip of the bar, if not at 100%. */
|
||||
if (has_tip && pad_count < bar_area_width) {
|
||||
append_to_buffer(style->tip);
|
||||
pad_count += style->tip.width;
|
||||
}
|
||||
|
||||
/* A partial cell, if below 100% and there are intermediates. */
|
||||
if (pad_count < bar_area_width && full_cell_index > 1 && !has_tip) {
|
||||
double exact_width = (((double) bar_area_width) * bar_percentage) / 100.0;
|
||||
double cell_portion = exact_width - (double) filled_bar_width;
|
||||
double cell_index_double = ((double) full_cell_index) * cell_portion;
|
||||
size_t cell_index = (size_t) cell_index_double;
|
||||
|
||||
if (cell_index > full_cell_index)
|
||||
cell_index = full_cell_index;
|
||||
|
||||
append_to_buffer(style->filler[cell_index]);
|
||||
pad_count += style->filler[cell_index].width;
|
||||
if (0 == style->filler[cell_index].width)
|
||||
pad_count++;
|
||||
}
|
||||
|
||||
/* The spaces after the bar. */
|
||||
while (pad_count < bar_area_width) {
|
||||
append_to_buffer(style->filler[0]);
|
||||
pad_count += style->filler[0].width;
|
||||
if (0 == style->filler[0].width)
|
||||
pad_count++;
|
||||
}
|
||||
|
||||
if (bar_sides) {
|
||||
/* The closure of the bar area. */
|
||||
if (buffer_offset < buffer_size - 1)
|
||||
buffer[buffer_offset++] = ']';
|
||||
}
|
||||
|
||||
/* The percentage. */
|
||||
if (after_bar_bytes > 0 && after_bar_bytes < (buffer_size - 1 - buffer_offset)) {
|
||||
memmove(buffer + buffer_offset, after_bar, after_bar_bytes);
|
||||
buffer_offset += after_bar_bytes;
|
||||
}
|
||||
|
||||
buffer[buffer_offset] = '\0';
|
||||
|
||||
return buffer_offset;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a progress bar to a buffer, in unknown-size mode - just a moving
|
||||
* indicator. The total width of the content is bounded to the given width.
|
||||
* Returns the number of bytes written to the buffer.
|
||||
*
|
||||
* If "bar_sides" is false, only the bar itself is rendered, not the opening
|
||||
* and closing characters.
|
||||
*
|
||||
* This is only called by pv_formatter_progress().
|
||||
*/
|
||||
static pvdisplay_bytecount_t pv_formatter_progress_unknownsize(pvformatter_args_t args, char *buffer,
|
||||
pvdisplay_bytecount_t buffer_size, bool bar_sides)
|
||||
{
|
||||
pvdisplay_bytecount_t buffer_offset;
|
||||
pvdisplay_width_t bar_area_width, pad_count;
|
||||
double indicator_position, padding_width;
|
||||
pvbarstyle_t style;
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (args->segment->parameter > 0 && args->segment->parameter <= PV_BARSTYLE_MAX) {
|
||||
style = &(args->display->barstyle[args->segment->parameter - 1]);
|
||||
} else {
|
||||
style = &(args->display->barstyle[0]);
|
||||
}
|
||||
|
||||
if (bar_sides) {
|
||||
if (args->segment->width < (style->indicator.width + 3))
|
||||
return 0;
|
||||
bar_area_width = args->segment->width - (style->indicator.width + 2);
|
||||
} else {
|
||||
if (args->segment->width < (style->indicator.width + 2))
|
||||
return 0;
|
||||
bar_area_width = args->segment->width - style->indicator.width;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that pv_calculate_transfer_rate() sets the percentage when
|
||||
* the size is unknown to a value that goes 0 - 200 and resets, so
|
||||
* here this is used make values above 100 send the indicator back
|
||||
* down again, so it moves back and forth.
|
||||
*/
|
||||
indicator_position = args->calc->percentage;
|
||||
if (indicator_position > 200.0)
|
||||
#if HAVE_FMOD
|
||||
indicator_position = fmod(indicator_position, 200.0);
|
||||
#else
|
||||
{
|
||||
while (indicator_position > 200.0)
|
||||
indicator_position -= 200.0;
|
||||
}
|
||||
#endif
|
||||
if (indicator_position > 100.0)
|
||||
indicator_position = 200.0 - indicator_position;
|
||||
if (indicator_position < 0.0)
|
||||
indicator_position = 0.0;
|
||||
|
||||
buffer_offset = 0;
|
||||
|
||||
if (bar_sides) {
|
||||
/* The opening of the bar area. */
|
||||
buffer[buffer_offset++] = '[';
|
||||
}
|
||||
|
||||
/* The spaces before the indicator. */
|
||||
pad_count = 0;
|
||||
padding_width = (((double) bar_area_width) * indicator_position) / 100.0;
|
||||
while (pad_count < bar_area_width && pad_count < (pvdisplay_width_t) padding_width) {
|
||||
append_to_buffer(style->filler[0]);
|
||||
pad_count += style->filler[0].width;
|
||||
if (0 == style->filler[0].width)
|
||||
pad_count++;
|
||||
}
|
||||
|
||||
/* The indicator. */
|
||||
if (buffer_offset < buffer_size - style->indicator.bytes) {
|
||||
append_to_buffer(style->indicator);
|
||||
}
|
||||
|
||||
/* The spaces after the indicator. */
|
||||
while (pad_count < bar_area_width) {
|
||||
append_to_buffer(style->filler[0]);
|
||||
pad_count += style->filler[0].width;
|
||||
if (0 == style->filler[0].width)
|
||||
pad_count++;
|
||||
}
|
||||
|
||||
if (bar_sides) {
|
||||
/* The closure of the bar area. */
|
||||
if (buffer_offset < buffer_size - 1)
|
||||
buffer[buffer_offset++] = ']';
|
||||
}
|
||||
|
||||
buffer[buffer_offset] = '\0';
|
||||
|
||||
return buffer_offset;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Progress bar.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_progress(pvformatter_args_t args)
|
||||
{
|
||||
char content[4096]; /* flawfinder: ignore - always bounded */
|
||||
pvdisplay_bytecount_t bytes;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
if (0 == args->segment->parameter) {
|
||||
const char *default_name;
|
||||
default_name = args->control->default_bar_style;
|
||||
/*@-branchstate@ */
|
||||
if (NULL == default_name)
|
||||
default_name = "plain";
|
||||
/*@+branchstate@ */
|
||||
/* splint - it doesn't matter that default_name may be static. */
|
||||
args->segment->parameter = 1 + pv_display_barstyle_index(args, default_name);
|
||||
}
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
if (args->control->size > 0 || args->control->rate_gauge) {
|
||||
/* Known size or rate gauge - bar with percentage. */
|
||||
bytes = pv_formatter_progress_knownsize(args, content, sizeof(content), true, true, true);
|
||||
} else {
|
||||
/* Unknown size - back-and-forth moving indicator. */
|
||||
bytes = pv_formatter_progress_unknownsize(args, content, sizeof(content), true);
|
||||
}
|
||||
|
||||
content[bytes] = '\0';
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Progress bar, without sides and without a number afterwards.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_progress_bar_only(pvformatter_args_t args)
|
||||
{
|
||||
char content[4096]; /* flawfinder: ignore - always bounded */
|
||||
pvdisplay_bytecount_t bytes;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
if (0 == args->segment->parameter) {
|
||||
const char *default_name;
|
||||
default_name = args->control->default_bar_style;
|
||||
/*@-branchstate@ */
|
||||
if (NULL == default_name)
|
||||
default_name = "plain";
|
||||
/*@+branchstate@ */
|
||||
/* splint - it doesn't matter that default_name may be static. */
|
||||
args->segment->parameter = 1 + pv_display_barstyle_index(args, default_name);
|
||||
}
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
if (args->control->size > 0 || args->control->rate_gauge) {
|
||||
/* Known size or rate gauge - bar with percentage. */
|
||||
bytes = pv_formatter_progress_knownsize(args, content, sizeof(content), false, true, false);
|
||||
} else {
|
||||
/* Unknown size - back-and-forth moving indicator. */
|
||||
bytes = pv_formatter_progress_unknownsize(args, content, sizeof(content), false);
|
||||
}
|
||||
|
||||
content[bytes] = '\0';
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The number after the progress bar.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_progress_amount_only(pvformatter_args_t args)
|
||||
{
|
||||
char content[256]; /* flawfinder: ignore - always bounded */
|
||||
pvdisplay_bytecount_t bytes;
|
||||
|
||||
memset(content, 0, sizeof(content));
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
if (args->control->numeric) {
|
||||
/* Numeric mode - percentage as a rounded integer with no suffix. */
|
||||
(void) pv_snprintf(content, sizeof(content), "%.0f", args->calc->percentage);
|
||||
bytes = strlen(content); /* flawfinder: ignore */
|
||||
/* flawfinder: always \0-terminated by pv_snprintf() and the earlier memset(). */
|
||||
} else if (args->control->size > 0 || args->control->rate_gauge) {
|
||||
/* Known size or rate gauge - percentage or rate. */
|
||||
bytes = pv_formatter_progress_knownsize(args, content, sizeof(content), false, false, true);
|
||||
} else {
|
||||
/* Unknown size - no number. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
content[bytes] = '\0';
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Formatter function for the current rate of transfer.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Transfer rate.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_rate(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore - always bounded */
|
||||
|
||||
args->display->showing_rate = true;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
/*@-mustfreefresh@ */
|
||||
if (args->control->numeric) {
|
||||
/* Numeric - raw value without suffix. */
|
||||
(void) pv_snprintf(content, sizeof(content),
|
||||
"%.4Lf", ((args->control->bits ? 8.0 : 1.0) * args->calc->transfer_rate));
|
||||
} else if (args->control->bits && !args->control->linemode) {
|
||||
/* Bits per second. */
|
||||
pv_describe_amount(content, sizeof(content), "[%s]",
|
||||
8 * args->calc->transfer_rate, "", _("b/s"), args->display->count_type);
|
||||
} else {
|
||||
/* Bytes or lines per second. */
|
||||
pv_describe_amount(content, sizeof(content),
|
||||
"[%s]", args->calc->transfer_rate, _("/s"), _("B/s"), args->display->count_type);
|
||||
}
|
||||
/*@+mustfreefresh@ *//* splint - false positives from gettext(). */
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Formatter function for ratio of bytes transferred by the other monitored
|
||||
* side to bytes transferred by this side.
|
||||
*
|
||||
* Copyright 2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Ratio of bytes or lines transferred by the other monitored side ("-M
|
||||
* both") to the bytes or lines transferred by this side.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_ratio(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore - always bounded */
|
||||
|
||||
args->display->showing_ratio = true;
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
if (0 == args->transfer->otherside_transferred || 0 == args->transfer->transferred) {
|
||||
(void) pv_snprintf(content, sizeof(content), "%s:%s", "-", "-");
|
||||
} else if (args->transfer->otherside_transferred == args->transfer->transferred) {
|
||||
(void) pv_snprintf(content, sizeof(content), "%d:%d", 1, 1);
|
||||
} else {
|
||||
long double side1, side2, ratio;
|
||||
|
||||
side1 = (long double) (args->transfer->otherside_transferred);
|
||||
side2 = (long double) (args->transfer->transferred);
|
||||
|
||||
if (side1 > side2) {
|
||||
ratio = side1 / side2;
|
||||
(void) pv_snprintf(content, sizeof(content), "%.4Lg:%d", ratio, 1);
|
||||
} else {
|
||||
ratio = side2 / side1;
|
||||
(void) pv_snprintf(content, sizeof(content), "%d:%.4Lg", 1, ratio);
|
||||
}
|
||||
}
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Formatter function for ECMA-48 SGR codes.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct sgr_keyword_map_s {
|
||||
/*@null@ */ const char *keyword;
|
||||
uint8_t bytes;
|
||||
uint8_t code;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return an array mapping keywords to ECMA-48 SGR code numbers.
|
||||
*/
|
||||
/*@keep@ */ static struct sgr_keyword_map_s *sgr_keywords(void)
|
||||
{
|
||||
/*@keep@ */ static struct sgr_keyword_map_s keywords[] = {
|
||||
{ "reset", 0, 0 },
|
||||
{ "none", 0, 0 },
|
||||
{ "bold", 0, 1 },
|
||||
{ "dim", 0, 2 },
|
||||
{ "italic", 0, 3 },
|
||||
{ "underscore", 0, 4 },
|
||||
{ "underline", 0, 4 },
|
||||
{ "blink", 0, 5 },
|
||||
{ "reverse", 0, 7 },
|
||||
{ "no-bold", 0, 22 }, /* same as no-dim */
|
||||
{ "no-dim", 0, 22 },
|
||||
{ "no-italic", 0, 23 },
|
||||
{ "no-underscore", 0, 24 },
|
||||
{ "no-underline", 0, 24 },
|
||||
{ "no-blink", 0, 25 },
|
||||
{ "no-reverse", 0, 27 },
|
||||
{ "black", 0, 30 },
|
||||
{ "red", 0, 31 },
|
||||
{ "green", 0, 32 },
|
||||
{ "brown", 0, 33 },
|
||||
{ "yellow", 0, 33 },
|
||||
{ "blue", 0, 34 },
|
||||
{ "magenta", 0, 35 },
|
||||
{ "cyan", 0, 36 },
|
||||
{ "white", 0, 37 },
|
||||
{ "fg-black", 0, 30 },
|
||||
{ "fg-red", 0, 31 },
|
||||
{ "fg-green", 0, 32 },
|
||||
{ "fg-brown", 0, 33 },
|
||||
{ "fg-yellow", 0, 33 },
|
||||
{ "fg-blue", 0, 34 },
|
||||
{ "fg-magenta", 0, 35 },
|
||||
{ "fg-cyan", 0, 36 },
|
||||
{ "fg-white", 0, 37 },
|
||||
{ "fg-default", 0, 39 },
|
||||
{ "bg-black", 0, 40 },
|
||||
{ "bg-red", 0, 41 },
|
||||
{ "bg-green", 0, 42 },
|
||||
{ "bg-brown", 0, 43 },
|
||||
{ "bg-yellow", 0, 43 },
|
||||
{ "bg-blue", 0, 44 },
|
||||
{ "bg-magenta", 0, 45 },
|
||||
{ "bg-cyan", 0, 46 },
|
||||
{ "bg-white", 0, 47 },
|
||||
{ "bg-default", 0, 49 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/* Calculate the lengths of each keyword on the first call. */
|
||||
if (0 == keywords[0].bytes) {
|
||||
int keyword_index;
|
||||
for (keyword_index = 0; NULL != keywords[keyword_index].keyword; keyword_index++) {
|
||||
keywords[keyword_index].bytes = strlen(keywords[keyword_index].keyword); /* flawfinder: ignore */
|
||||
/* flawfinder - strlen() on a static null-terminated string is OK. */
|
||||
}
|
||||
}
|
||||
|
||||
/*@-compmempass@ */
|
||||
return keywords;
|
||||
/*@+compmempass@ */
|
||||
/*
|
||||
* splint - no other way to pass static back without a false
|
||||
* positive warning about a memory leak.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display SGR codes if colour output is supported.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_sgr(pvformatter_args_t args)
|
||||
{
|
||||
/*@keep@ */ static struct sgr_keyword_map_s *keywords;
|
||||
char content[1024]; /* flawfinder: ignore */
|
||||
size_t content_buffer_size = sizeof(content);
|
||||
pvdisplay_bytecount_t write_position, read_position, keyword_start, keyword_length;
|
||||
int numeric_value, code_count, most_recent_code;
|
||||
|
||||
/* flawfinder - null-terminated and bounded with pv_snprintf(). */
|
||||
|
||||
if (!args->display->colour_permitted)
|
||||
return 0;
|
||||
|
||||
args->display->format_uses_colour = true;
|
||||
|
||||
if (!args->status->terminal_supports_colour)
|
||||
return 0;
|
||||
if (NULL == args->segment->string_parameter)
|
||||
return 0;
|
||||
if (0 == args->segment->string_parameter_bytes)
|
||||
return 0;
|
||||
|
||||
keywords = sgr_keywords();
|
||||
|
||||
write_position = 0;
|
||||
content[0] = '\0';
|
||||
|
||||
debug("%p+%d [%.*s]", args->segment->string_parameter, args->segment->string_parameter_bytes,
|
||||
args->segment->string_parameter_bytes, args->segment->string_parameter);
|
||||
|
||||
read_position = 0;
|
||||
keyword_start = 0;
|
||||
keyword_length = 0;
|
||||
numeric_value = -1;
|
||||
code_count = 0;
|
||||
most_recent_code = -1;
|
||||
|
||||
while (read_position < args->segment->string_parameter_bytes) {
|
||||
char read_char = args->segment->string_parameter[read_position++];
|
||||
if ((',' == read_char) || (';' == read_char)) {
|
||||
keyword_length = read_position - keyword_start;
|
||||
if (keyword_length > 0)
|
||||
keyword_length--;
|
||||
} else {
|
||||
if ((read_char >= '0' && read_char <= '9')
|
||||
&& (numeric_value >= 0 || keyword_start == read_position - 1)) {
|
||||
if (keyword_start == read_position - 1)
|
||||
numeric_value = 0;
|
||||
numeric_value = numeric_value * 10 + (int) (read_char - '0');
|
||||
} else {
|
||||
numeric_value = -1;
|
||||
}
|
||||
if (read_position >= args->segment->string_parameter_bytes) {
|
||||
keyword_length = read_position - keyword_start;
|
||||
}
|
||||
}
|
||||
if (keyword_length > 0) {
|
||||
int code = -1;
|
||||
|
||||
debug("keyword@%d+%d: [%.*s]; numeric=%d", keyword_start, keyword_length, keyword_length,
|
||||
&(args->segment->string_parameter[keyword_start]), numeric_value);
|
||||
|
||||
if (numeric_value >= 0 && numeric_value < 255) {
|
||||
code = numeric_value;
|
||||
} else {
|
||||
int keyword_index;
|
||||
for (keyword_index = 0; -1 == code && NULL != keywords[keyword_index].keyword;
|
||||
keyword_index++) {
|
||||
if (keyword_length != keywords[keyword_index].bytes)
|
||||
continue;
|
||||
if (0 !=
|
||||
strncmp(keywords[keyword_index].keyword,
|
||||
&(args->segment->string_parameter[keyword_start]), keyword_length))
|
||||
continue;
|
||||
code = (int) (keywords[keyword_index].code);
|
||||
}
|
||||
}
|
||||
|
||||
debug("code=%d", code);
|
||||
|
||||
if (code >= 0) {
|
||||
if (code_count > 15 && write_position < content_buffer_size) {
|
||||
write_position +=
|
||||
pv_snprintf(content + write_position, sizeof(content) - write_position,
|
||||
"%s", "m");
|
||||
code_count = 0;
|
||||
}
|
||||
if (0 == code_count && write_position < content_buffer_size) {
|
||||
write_position +=
|
||||
pv_snprintf(content + write_position, sizeof(content) - write_position,
|
||||
"%s", "\033[");
|
||||
} else if (write_position < content_buffer_size) {
|
||||
write_position +=
|
||||
pv_snprintf(content + write_position, sizeof(content) - write_position,
|
||||
"%s", ";");
|
||||
}
|
||||
if (write_position < content_buffer_size) {
|
||||
write_position +=
|
||||
pv_snprintf(content + write_position, sizeof(content) - write_position,
|
||||
"%d", code);
|
||||
}
|
||||
code_count++;
|
||||
most_recent_code = code;
|
||||
}
|
||||
|
||||
keyword_length = 0;
|
||||
keyword_start = read_position;
|
||||
}
|
||||
}
|
||||
|
||||
if (code_count > 0 && write_position < content_buffer_size)
|
||||
write_position += pv_snprintf(content + write_position, sizeof(content) - write_position, "%s", "m");
|
||||
|
||||
if (most_recent_code > 0) {
|
||||
args->display->sgr_code_active = true;
|
||||
} else if (0 == most_recent_code) {
|
||||
args->display->sgr_code_active = false;
|
||||
}
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Formatter function for the elapsed transfer time.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Elapsed time.
|
||||
*/
|
||||
pvdisplay_bytecount_t pv_formatter_timer(pvformatter_args_t args)
|
||||
{
|
||||
char content[128]; /* flawfinder: ignore - bounded with pv_snprintf(). */
|
||||
long double elapsed_seconds;
|
||||
|
||||
args->display->showing_timer = true;
|
||||
|
||||
content[0] = '\0';
|
||||
|
||||
if (0 == args->buffer_size)
|
||||
return 0;
|
||||
|
||||
elapsed_seconds = args->transfer->elapsed_seconds;
|
||||
|
||||
/* The timer must always be positive. */
|
||||
if (elapsed_seconds < 0.0L)
|
||||
elapsed_seconds = 0.0L;
|
||||
|
||||
if (args->control->numeric) {
|
||||
/* Numeric mode - show the number of seconds, unformatted. */
|
||||
(void) pv_snprintf(content, sizeof(content), "%.4Lf", elapsed_seconds);
|
||||
} else if (elapsed_seconds > (long double) (999999.999999L * 86400.0L)) {
|
||||
/*
|
||||
* At a million days, the timer would be too wide, so avoid
|
||||
* an overflow.
|
||||
*/
|
||||
(void) pv_snprintf(content,
|
||||
sizeof(content),
|
||||
"%s:%02ld:%02ld:%02ld",
|
||||
">=1e6",
|
||||
(((long) (elapsed_seconds)) / 3600) %
|
||||
24, (((long) (elapsed_seconds)) / 60) % 60, ((long) (elapsed_seconds)) % 60);
|
||||
} else if (elapsed_seconds > (long double) 86400.0L) {
|
||||
/*
|
||||
* If the elapsed time is more than a day, include a day count as
|
||||
* well as hours, minutes, and seconds.
|
||||
*/
|
||||
(void) pv_snprintf(content,
|
||||
sizeof(content),
|
||||
"%ld:%02ld:%02ld:%02ld",
|
||||
((long) (elapsed_seconds)) / 86400,
|
||||
(((long) (elapsed_seconds)) / 3600) %
|
||||
24, (((long) (elapsed_seconds)) / 60) % 60, ((long) (elapsed_seconds)) % 60);
|
||||
} else {
|
||||
(void) pv_snprintf(content,
|
||||
sizeof(content),
|
||||
"%ld:%02ld:%02ld",
|
||||
((long) (elapsed_seconds)) / 3600,
|
||||
(((long) (elapsed_seconds)) / 60) % 60, ((long) (elapsed_seconds)) % 60);
|
||||
}
|
||||
|
||||
return pv_formatter_segmentcontent(content, args);
|
||||
}
|
||||
+1403
-522
File diff suppressed because it is too large
Load Diff
+186
-83
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Functions for converting strings to numbers.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* Distributed under the Artistic License v2.0; see `doc/COPYING'.
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -17,70 +17,98 @@
|
||||
* including <ctype.h> causes weird versioned glibc dependencies on certain
|
||||
* Red Hat systems, complicating package management.
|
||||
*/
|
||||
static bool pv__isdigit(char c)
|
||||
bool pv_isdigit(char c)
|
||||
{
|
||||
return ((c >= '0') && (c <= '9')) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the numeric value of "str", as an unsigned long long.
|
||||
* Return the numeric value of "str", as an off_t, where "str" is expected
|
||||
* to be a sequence of digits (without a thousands separator), possibly with
|
||||
* a fractional part, optionally followed by a units suffix such as "K" for
|
||||
* kibibytes. If "decimal_units" is true, suffixes are interpreted as
|
||||
* multiples of 1000, rather than multiples of 1024.
|
||||
*
|
||||
* If resultptr is not NULL, it is populated with the result as a long
|
||||
* double.
|
||||
*/
|
||||
unsigned long long pv_getnum_ull(const char *str)
|
||||
off_t pv_getnum_size(const char *str, bool decimal_units, /*@null@ */ long double *resultptr)
|
||||
{
|
||||
unsigned long long n = 0;
|
||||
unsigned long long decimal = 0;
|
||||
unsigned int decdivisor = 1;
|
||||
unsigned int shift = 0;
|
||||
off_t integral_part = 0;
|
||||
off_t fractional_part = 0;
|
||||
unsigned int fractional_divisor = 1;
|
||||
unsigned int binary_shift = 0;
|
||||
off_t decimal_multiplier = 0;
|
||||
size_t readpos = 0;
|
||||
|
||||
if (NULL == str)
|
||||
return n;
|
||||
if (NULL == str) {
|
||||
if (NULL != resultptr)
|
||||
*resultptr = 0.0;
|
||||
return (off_t) 0;
|
||||
}
|
||||
|
||||
while (str[0] != '\0' && (!pv__isdigit(str[0])))
|
||||
str++;
|
||||
/* Skip any non-numeric leading characters. */
|
||||
while (str[readpos] != '\0' && (!pv_isdigit(str[readpos])))
|
||||
readpos++;
|
||||
|
||||
for (; pv__isdigit(str[0]); str++) {
|
||||
n = n * 10;
|
||||
n += (unsigned long long) (str[0] - '0');
|
||||
/*
|
||||
* Parse the integral part of the number - the digits before the
|
||||
* decimal mark or units.
|
||||
*/
|
||||
for (; pv_isdigit(str[readpos]); readpos++) {
|
||||
integral_part = integral_part * 10;
|
||||
integral_part += (off_t) (str[readpos] - '0');
|
||||
}
|
||||
|
||||
/*
|
||||
* If a decimal value was given, skip the decimal part.
|
||||
* If the next character is a decimal mark, skip over it and parse
|
||||
* the following digits as the fractional part of the number.
|
||||
*
|
||||
* Note that the decimal mark is hard-coded as being either '.' or
|
||||
* ',' so this will fail if there are any locales whose decimal mark
|
||||
* is not one of those two characters.
|
||||
*/
|
||||
if (('.' == str[0]) || (',' == str[0])) {
|
||||
str++;
|
||||
for (; pv__isdigit(str[0]); str++) {
|
||||
if (decdivisor < 10000) {
|
||||
decimal = decimal * 10;
|
||||
decimal += (unsigned long long) (str[0] - '0');
|
||||
decdivisor = decdivisor * 10;
|
||||
if (('.' == str[readpos]) || (',' == str[readpos])) {
|
||||
readpos++;
|
||||
for (; pv_isdigit(str[readpos]); readpos++) {
|
||||
/* Stop counting below 0.0001. */
|
||||
if (fractional_divisor < 10000) {
|
||||
fractional_part = fractional_part * 10;
|
||||
fractional_part += (off_t) (str[readpos] - '0');
|
||||
fractional_divisor = fractional_divisor * 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse any units given (K=KiB=*1024, M=MiB=1024KiB, G=GiB=1024MiB,
|
||||
* T=TiB=1024GiB).
|
||||
* T=TiB=1024GiB; replace 1024 with 1000 if decimal_units is true).
|
||||
*/
|
||||
if (str[0] != '\0') {
|
||||
while ((' ' == str[0]) || ('\t' == str[0]))
|
||||
str++;
|
||||
switch (str[0]) {
|
||||
if (str[readpos] != '\0') {
|
||||
/* Skip any spaces or tabs after the digits. */
|
||||
while ((' ' == str[readpos]) || ('\t' == str[readpos]))
|
||||
readpos++;
|
||||
switch (str[readpos]) {
|
||||
case 'k':
|
||||
case 'K':
|
||||
shift = 10;
|
||||
binary_shift = 10;
|
||||
decimal_multiplier = 1000;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
shift = 20;
|
||||
binary_shift = 20;
|
||||
decimal_multiplier = 1000000;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
shift = 30;
|
||||
binary_shift = 30;
|
||||
decimal_multiplier = 1000000000;
|
||||
break;
|
||||
case 't':
|
||||
case 'T':
|
||||
shift = 40;
|
||||
binary_shift = 40;
|
||||
decimal_multiplier = 1000000000000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -88,109 +116,165 @@ unsigned long long pv_getnum_ull(const char *str)
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary left-shift the supplied number by "shift" times, i.e.
|
||||
* If decimal_units is true, set binary_shift to zero; if false, set
|
||||
* decimal_multiplier to zero. This is so that only one of the two
|
||||
* multipliers can be active.
|
||||
*/
|
||||
if (decimal_units) {
|
||||
binary_shift = 0;
|
||||
} else {
|
||||
decimal_multiplier = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary left-shift the supplied number by "binary_shift" times, i.e.
|
||||
* apply the given units (KiB, MiB, etc) to it, but never shift left
|
||||
* more than 30 at a time to avoid overflows.
|
||||
*/
|
||||
while (shift > 0) {
|
||||
while (binary_shift > 0) {
|
||||
unsigned int shiftby;
|
||||
|
||||
shiftby = shift;
|
||||
shiftby = binary_shift;
|
||||
if (shiftby > 30)
|
||||
shiftby = 30;
|
||||
|
||||
n = n << shiftby;
|
||||
decimal = decimal << shiftby;
|
||||
shift -= shiftby;
|
||||
/*@-shiftimplementation@ */
|
||||
/*
|
||||
* splint note: ignore the fact that the types being shifted
|
||||
* are signed, because they are definitely not negative.
|
||||
*/
|
||||
integral_part = (off_t) (integral_part << shiftby);
|
||||
fractional_part = (off_t) (fractional_part << shiftby);
|
||||
/*@+shiftimplementation@ */
|
||||
|
||||
binary_shift -= shiftby;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add any decimal component.
|
||||
* Multiply the supplied number by the decimal multiplier.
|
||||
*/
|
||||
decimal = decimal / decdivisor;
|
||||
n += decimal;
|
||||
if (decimal_multiplier > 0) {
|
||||
integral_part = integral_part * decimal_multiplier;
|
||||
fractional_part = fractional_part * decimal_multiplier;
|
||||
}
|
||||
|
||||
return n;
|
||||
/*
|
||||
* Add the fractional part, divided by its divisor, to the integral
|
||||
* part, now that the multiplier for the units has been applied.
|
||||
*/
|
||||
if (NULL != resultptr) {
|
||||
*resultptr = ((long double) fractional_part) / (long double) fractional_divisor;
|
||||
*resultptr += (long double) integral_part;
|
||||
}
|
||||
fractional_part = fractional_part / fractional_divisor;
|
||||
integral_part += fractional_part;
|
||||
|
||||
if (NULL != resultptr) {
|
||||
debug("%s [%s] = %lld = %Lf", str, decimal_units ? "decimal" : "binary", (long long) integral_part,
|
||||
*resultptr);
|
||||
} else {
|
||||
debug("%s [%s] = %lld", str, decimal_units ? "decimal" : "binary", (long long) integral_part);
|
||||
}
|
||||
|
||||
return integral_part;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the numeric value of "str", as a double.
|
||||
* Return the numeric value of "str", as a double, where "str" is expected
|
||||
* to be a positive decimal number expressing a time interval.
|
||||
*/
|
||||
double pv_getnum_d(const char *str)
|
||||
double pv_getnum_interval(const char *str)
|
||||
{
|
||||
double n = 0.0;
|
||||
double result = 0.0;
|
||||
double step = 1;
|
||||
|
||||
if (NULL == str)
|
||||
return n;
|
||||
return 0.0;
|
||||
|
||||
while (str[0] != '\0' && (!pv__isdigit(str[0])))
|
||||
/* Skip any non-digit characters at the start. */
|
||||
while (str[0] != '\0' && (!pv_isdigit(str[0])))
|
||||
str++;
|
||||
|
||||
for (; pv__isdigit(str[0]); str++) {
|
||||
n = n * 10;
|
||||
n += (double) (str[0] - '0');
|
||||
/* Parse the digits before the decimal mark. */
|
||||
for (; pv_isdigit(str[0]); str++) {
|
||||
result = result * 10;
|
||||
result += (double) (str[0] - '0');
|
||||
}
|
||||
|
||||
/* If there is no decimal mark, return the value as-is. */
|
||||
if ((str[0] != '.') && (str[0] != ','))
|
||||
return n;
|
||||
return result;
|
||||
|
||||
/* Move past the decimal mark. */
|
||||
str++;
|
||||
|
||||
for (; pv__isdigit(str[0]) && step < 1000000; str++) {
|
||||
/* Parse the digits after the decimal mark, up to 0.0000001. */
|
||||
for (; pv_isdigit(str[0]) && step < 1000000; str++) {
|
||||
step = step * 10;
|
||||
n += ((double) (str[0] - '0')) / step;
|
||||
result += ((double) (str[0] - '0')) / step;
|
||||
}
|
||||
|
||||
return n;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the numeric value of "str", as an unsigned int.
|
||||
* Return the numeric value of "str", as an unsigned int, following the same
|
||||
* rules as pv_getnum_size(), expecting "str" to express a value to be used
|
||||
* as a count (such as number of screen columns, or size of a buffer).
|
||||
*/
|
||||
unsigned int pv_getnum_ui(const char *str)
|
||||
unsigned int pv_getnum_count(const char *str, bool decimal_units)
|
||||
{
|
||||
return (unsigned int) pv_getnum_ull(str);
|
||||
return (unsigned int) pv_getnum_size(str, decimal_units, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return nonzero if the given string is not a valid number of the given
|
||||
* type.
|
||||
* Return true if the given string is a valid number of the given type.
|
||||
*/
|
||||
int pv_getnum_check(const char *str, pv_numtype_t type)
|
||||
bool pv_getnum_check(const char *str, pv_numtype type)
|
||||
{
|
||||
if (0 == str)
|
||||
return 1;
|
||||
if (NULL == str)
|
||||
return false;
|
||||
|
||||
/* Skip leading spaces and tabs. */
|
||||
while ((' ' == str[0]) || ('\t' == str[0]))
|
||||
str++;
|
||||
|
||||
if (!pv__isdigit(str[0]))
|
||||
return 1;
|
||||
/* If the next character isn't a digit, this isn't a number. */
|
||||
if (!pv_isdigit(str[0]))
|
||||
return false;
|
||||
|
||||
for (; pv__isdigit(str[0]); str++);
|
||||
|
||||
if (('.' == str[0]) || (',' == str[0])) {
|
||||
if (type == PV_NUMTYPE_INTEGER)
|
||||
return 1;
|
||||
str++;
|
||||
for (; pv__isdigit(str[0]); str++);
|
||||
}
|
||||
|
||||
if ('\0' == str[0])
|
||||
return 0;
|
||||
/* Skip over the digits. */
|
||||
for (; pv_isdigit(str[0]); str++);
|
||||
|
||||
/*
|
||||
* Suffixes are not allowed for doubles, only for integers.
|
||||
* If there's a decimal mark (see note in pv_getnum_size() above),
|
||||
* check that too.
|
||||
*/
|
||||
if (type == PV_NUMTYPE_DOUBLE)
|
||||
return 1;
|
||||
if (('.' == str[0]) || (',' == str[0])) {
|
||||
/* Bare integers should have no decimal mark. */
|
||||
if (type == PV_NUMTYPE_BARE_INTEGER)
|
||||
return false;
|
||||
/* Skip the decimal mark, then all digits. */
|
||||
str++;
|
||||
for (; pv_isdigit(str[0]); str++);
|
||||
}
|
||||
|
||||
/* If the string ends here, this is a valid number. */
|
||||
if ('\0' == str[0])
|
||||
return true;
|
||||
|
||||
/* A units suffix is only allowed for ANY_WITH_SUFFIX. */
|
||||
if (type != PV_NUMTYPE_ANY_WITH_SUFFIX)
|
||||
return false;
|
||||
|
||||
/* Skip trailing spaces or tabs. */
|
||||
while ((' ' == str[0]) || ('\t' == str[0]))
|
||||
str++;
|
||||
|
||||
/* Check the units suffix is known. */
|
||||
switch (str[0]) {
|
||||
case 'k':
|
||||
case 'K':
|
||||
@@ -203,13 +287,32 @@ int pv_getnum_check(const char *str, pv_numtype_t type)
|
||||
str++;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the string has trailing text, it's not a valid number. */
|
||||
if (str[0] != '\0')
|
||||
return 1;
|
||||
return false;
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
/*
|
||||
* Return a value representing "amount" as a percentage of "total", i.e.
|
||||
* 100*amount/total. If "total" is zero or less, return 0.
|
||||
*/
|
||||
double pv_percentage(off_t amount, const off_t total)
|
||||
{
|
||||
double amount_as_double;
|
||||
|
||||
if (total < 1)
|
||||
return 0.0;
|
||||
|
||||
amount_as_double = (double) amount;
|
||||
|
||||
amount_as_double *= 100.0;
|
||||
amount_as_double /= (double) total;
|
||||
|
||||
return amount_as_double;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Functions for setting the process title.
|
||||
*
|
||||
* Copyright 2024-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if ! HAVE_SETPROCTITLE
|
||||
extern char **environ;
|
||||
|
||||
/*@null@*/ static char **base_argv = NULL;
|
||||
static size_t space_available = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Assuming the environment comes after the command line arguments, make a
|
||||
* duplicate of the environment array and all its values, to allow the
|
||||
* process title to use the space the environment used to occupy.
|
||||
*
|
||||
* The logic for this was derived from util-linux-ng.
|
||||
*/
|
||||
/*@-mustfreefresh@ */
|
||||
/*@-nullstate@ */
|
||||
void initproctitle(int argc, char **argv)
|
||||
{
|
||||
char **original_environment = environ;
|
||||
char **new_environment;
|
||||
size_t env_array_size, env_index;
|
||||
|
||||
/* Find the number of entries in the environment array. */
|
||||
for (env_array_size = 0; environ[env_array_size] != NULL; env_array_size++);
|
||||
|
||||
/* Allocate a new environment array. */
|
||||
new_environment = (char **) malloc(sizeof(char *) * (env_array_size + 1));
|
||||
if (NULL == new_environment)
|
||||
return;
|
||||
|
||||
/* Duplicate the strings in the environment. */
|
||||
for (env_index = 0; original_environment[env_index] != NULL; env_index++) {
|
||||
new_environment[env_index] = pv_strdup(original_environment[env_index]);
|
||||
if (NULL == new_environment[env_index])
|
||||
return;
|
||||
}
|
||||
new_environment[env_index] = NULL;
|
||||
|
||||
base_argv = argv;
|
||||
|
||||
/* Work out how much room is available. */
|
||||
if (env_index > 0) {
|
||||
/* From argv[0] to the end of the last environment value. */
|
||||
space_available = (size_t)
|
||||
(original_environment[env_index - 1] + strlen(original_environment[env_index - 1]) - argv[0]); /* flawfinder: ignore */
|
||||
} else if (argc > 0) {
|
||||
/* No environment; from argv[0] to the end of the last argument. */
|
||||
space_available = (size_t) (argv[argc - 1] + strlen(argv[argc - 1]) - argv[0]); /* flawfinder: ignore */
|
||||
}
|
||||
|
||||
/*
|
||||
* flawfinder - the OS is supposed to guarantee that the environment
|
||||
* and argument strings are null-terminated.
|
||||
*/
|
||||
|
||||
environ = new_environment;
|
||||
}
|
||||
|
||||
/*@+nullstate@ */
|
||||
/*@+mustfreefresh@ */
|
||||
|
||||
|
||||
/*
|
||||
* Set the process title visible to ps(1), by overwriting argv[0] with the
|
||||
* given printf() format string.
|
||||
*/
|
||||
void setproctitle(const char *format, ...)
|
||||
{
|
||||
char title[1024]; /* flawfinder: ignore */
|
||||
size_t length;
|
||||
va_list ap;
|
||||
|
||||
/* flawfinder - buffer is zeroed and calls using it are bounded. */
|
||||
|
||||
if (NULL == base_argv)
|
||||
return;
|
||||
|
||||
memset(title, 0, sizeof(title));
|
||||
|
||||
va_start(ap, format);
|
||||
(void) vsnprintf(title, sizeof(title) - 1, format, ap); /* flawfinder: ignore */
|
||||
va_end(ap);
|
||||
|
||||
/*
|
||||
* flawfinder - the format is explicitly caller-supplied. Callers
|
||||
* of this function are all passing fixed format strings and not
|
||||
* user-supplied formats.
|
||||
*/
|
||||
|
||||
length = strlen(title); /* flawfinder: ignore */
|
||||
/* flawfinder - a byte was left at the end to force null-termination. */
|
||||
|
||||
if (length > space_available - 2)
|
||||
length = space_available - 2;
|
||||
|
||||
(void) pv_snprintf(base_argv[0], space_available, "%s", title);
|
||||
if (space_available > length)
|
||||
memset(base_argv[0] + length, 0, space_available - length);
|
||||
}
|
||||
|
||||
#endif
|
||||
+682
@@ -0,0 +1,682 @@
|
||||
/*
|
||||
* Remote-control and remote-query functions.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2026 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef PV_REMOTE_CONTROL
|
||||
|
||||
/* Structure for transferring settings with --remote. */
|
||||
struct remote_msg {
|
||||
bool progress; /* progress bar flag */
|
||||
bool timer; /* timer flag */
|
||||
bool eta; /* ETA flag */
|
||||
bool fineta; /* absolute ETA flag */
|
||||
bool rate; /* rate counter flag */
|
||||
bool average_rate; /* average rate counter flag */
|
||||
bool bytes; /* bytes transferred flag */
|
||||
bool bufpercent; /* transfer buffer percentage flag */
|
||||
size_t lastwritten; /* last-written bytes count */
|
||||
long double rate_limit; /* rate limit, in bytes per second */
|
||||
size_t buffer_size; /* buffer size, in bytes (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
double interval; /* interval between updates */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
bool width_set_manually; /* width was set manually, not detected */
|
||||
bool height_set_manually; /* height was set manually, not detected */
|
||||
bool rate_limit_specified; /* whether a rate limit value was set */
|
||||
bool rate_limit_active; /* whether rate limiting is in effect (>0) */
|
||||
char name[256]; /* flawfinder: ignore */
|
||||
char format[256]; /* flawfinder: ignore */
|
||||
char extra_display[256]; /* flawfinder: ignore */
|
||||
};
|
||||
|
||||
/* Structure for transferring transfer state with --query. */
|
||||
struct query_msg {
|
||||
long double elapsed_seconds; /* from state.transfer */
|
||||
off_t transferred; /* from state.transfer */
|
||||
off_t size; /* from state.control */
|
||||
bool response; /* true if this is the response signal. */
|
||||
};
|
||||
|
||||
/*
|
||||
* flawfinder rationale: name, format, and extra_display are always
|
||||
* explicitly zeroed and bounded to one less than their size so they are
|
||||
* always \0 terminated.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Set the options of a remote process by writing them to a file, sending a
|
||||
* signal to the receiving process, and waiting for the message to be
|
||||
* consumed by the remote process.
|
||||
*
|
||||
* Returns nonzero on error.
|
||||
*/
|
||||
int pv_remote_set(pvstate_t state, pid_t remote)
|
||||
{
|
||||
char control_filename[4096]; /* flawfinder: ignore */
|
||||
FILE *control_fptr;
|
||||
struct remote_msg msgbuf;
|
||||
pid_t signal_sender;
|
||||
long timeout;
|
||||
bool received;
|
||||
|
||||
/*
|
||||
* flawfinder rationale: buffer is large enough, explicitly zeroed,
|
||||
* and always bounded properly as we are only writing to it with
|
||||
* pv_snprintf().
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check that the remote process exists.
|
||||
*/
|
||||
if (kill((pid_t) (remote), 0) != 0) {
|
||||
pv_perror("%s %u", _("pid"), remote);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy parameters into message buffer.
|
||||
*/
|
||||
memset(&msgbuf, 0, sizeof(msgbuf));
|
||||
msgbuf.progress = state->control.format_option.progress;
|
||||
msgbuf.timer = state->control.format_option.timer;
|
||||
msgbuf.eta = state->control.format_option.eta;
|
||||
msgbuf.fineta = state->control.format_option.fineta;
|
||||
msgbuf.rate = state->control.format_option.rate;
|
||||
msgbuf.average_rate = state->control.format_option.average_rate;
|
||||
msgbuf.bytes = state->control.format_option.bytes;
|
||||
msgbuf.bufpercent = state->control.format_option.bufpercent;
|
||||
msgbuf.lastwritten = state->control.format_option.lastwritten;
|
||||
msgbuf.rate_limit = state->control.rate_limit;
|
||||
msgbuf.rate_limit_specified = state->control.rate_limit_specified;
|
||||
msgbuf.rate_limit_active = state->control.rate_limit_active;
|
||||
msgbuf.buffer_size = state->control.target_buffer_size;
|
||||
msgbuf.size = state->control.size;
|
||||
msgbuf.interval = state->control.interval;
|
||||
msgbuf.width = (unsigned int) (state->control.width);
|
||||
msgbuf.height = (unsigned int) (state->control.height);
|
||||
msgbuf.width_set_manually = state->control.width_set_manually;
|
||||
msgbuf.height_set_manually = state->control.height_set_manually;
|
||||
|
||||
if (state->control.name != NULL) {
|
||||
strncpy(msgbuf.name, state->control.name, sizeof(msgbuf.name) - 1); /* flawfinder: ignore */
|
||||
}
|
||||
if (state->control.format_string != NULL) {
|
||||
strncpy(msgbuf.format, state->control.format_string, sizeof(msgbuf.format) - 1); /* flawfinder: ignore */
|
||||
}
|
||||
if (state->control.extra_display_spec != NULL) {
|
||||
strncpy(msgbuf.extra_display, state->control.extra_display_spec, sizeof(msgbuf.extra_display) - 1); /* flawfinder: ignore */
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure parameters are within sensible bounds.
|
||||
*/
|
||||
if (msgbuf.width < 1)
|
||||
msgbuf.width = 80;
|
||||
if (msgbuf.height < 1)
|
||||
msgbuf.height = 25;
|
||||
if (msgbuf.width > 999999)
|
||||
msgbuf.width = 999999;
|
||||
if (msgbuf.height > 999999)
|
||||
msgbuf.height = 999999;
|
||||
if ((msgbuf.interval > 0) && (msgbuf.interval < 0.1))
|
||||
msgbuf.interval = 0.1;
|
||||
if (msgbuf.interval > 600)
|
||||
msgbuf.interval = 600;
|
||||
|
||||
/*
|
||||
* flawfinder rationale: name, format, and extra_display are
|
||||
* explicitly bounded to 1 less than the size of their buffer and
|
||||
* the buffer is \0 terminated by memset() earlier.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get the filename and file stream to use for remote control.
|
||||
*/
|
||||
memset(control_filename, 0, sizeof(control_filename));
|
||||
control_fptr = pv_open_controlfile(control_filename, sizeof(control_filename), (pid_t) getpid(), SIGUSR2, true);
|
||||
if (NULL == control_fptr) {
|
||||
pv_perror("%s", control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the message buffer to the remote control file, and close
|
||||
* it.
|
||||
*/
|
||||
if (1 != fwrite(&msgbuf, sizeof(msgbuf), 1, control_fptr)) {
|
||||
pv_perror("%s", control_filename);
|
||||
(void) fclose(control_fptr);
|
||||
(void) remove(control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
if (0 != fclose(control_fptr)) {
|
||||
pv_perror("%s", control_filename);
|
||||
(void) remove(control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear this process's "SIGUSR2 received" flag, and then send a
|
||||
* SIGUSR2 signal to the remote process, to tell it a message is
|
||||
* ready to read.
|
||||
*/
|
||||
signal_sender = 0;
|
||||
(void) pv_sigusr2_received(state, &signal_sender);
|
||||
if (kill((pid_t) (remote), SIGUSR2) != 0) {
|
||||
pv_perror("%s %u", _("pid"), remote);
|
||||
(void) remove(control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
debug("%s", "message sent");
|
||||
|
||||
/*
|
||||
* Wait for a signal from the remote process to say it has received
|
||||
* the message.
|
||||
*/
|
||||
|
||||
timeout = 1100000;
|
||||
received = false;
|
||||
|
||||
while (timeout > 10000 && !received) {
|
||||
struct timeval tv;
|
||||
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
/*@-nullpass@ *//* splint: NULL is OK with select() */
|
||||
(void) select(0, NULL, NULL, NULL, &tv);
|
||||
/*@+nullpass@ */
|
||||
timeout -= 10000;
|
||||
|
||||
if (pv_sigusr2_received(state, &signal_sender)) {
|
||||
if (signal_sender == remote) {
|
||||
debug("%s", "message received");
|
||||
received = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the remote control file.
|
||||
*/
|
||||
debug("%s: %s", "removing", control_filename);
|
||||
if (0 != remove(control_filename)) {
|
||||
pv_perror("%s", control_filename);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 if the message was received.
|
||||
*/
|
||||
if (received)
|
||||
return 0;
|
||||
|
||||
/*@-mustfreefresh@ */
|
||||
/*
|
||||
* splint note: the gettext calls made by _() cause memory leak
|
||||
* warnings, but in this case it's unavoidable, and mitigated by the
|
||||
* fact that each string is only translated once.
|
||||
*/
|
||||
pv_error("%u: %s", remote, _("message not received"));
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
/*@+mustfreefresh @ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for a --remote message (SIGUSR2), returning false if none was
|
||||
* found.
|
||||
*
|
||||
* If a message was received, update the current process's options with the
|
||||
* ones in the message.
|
||||
*
|
||||
* Note that this relies on pv_state_set_format_options() causing the output
|
||||
* format to be reparsed.
|
||||
*/
|
||||
static bool pv__rxsignal_usr2(pvstate_t state)
|
||||
{
|
||||
pid_t signal_sender;
|
||||
char control_filename[4096]; /* flawfinder: ignore */
|
||||
FILE *control_fptr;
|
||||
struct remote_msg msgbuf;
|
||||
pvformatoptions_s format_options;
|
||||
|
||||
/* flawfinder rationale: as above. */
|
||||
|
||||
/*
|
||||
* Return early if a SIGUSR2 signal has not been received.
|
||||
*/
|
||||
signal_sender = 0;
|
||||
if (!pv_sigusr2_received(state, &signal_sender))
|
||||
return false;
|
||||
|
||||
memset(control_filename, 0, sizeof(control_filename));
|
||||
control_fptr = pv_open_controlfile(control_filename, sizeof(control_filename), signal_sender, SIGUSR2, false);
|
||||
if (NULL == control_fptr) {
|
||||
pv_perror("%s", control_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the message buffer from the remote control file, and close
|
||||
* it.
|
||||
*/
|
||||
if (1 != fread(&msgbuf, sizeof(msgbuf), 1, control_fptr)) {
|
||||
pv_perror("%s", control_filename);
|
||||
(void) fclose(control_fptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 != fclose(control_fptr)) {
|
||||
pv_perror("%s", control_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a SIGUSR2 signal to the sending process, to tell it the
|
||||
* message has been received.
|
||||
*/
|
||||
if (kill(signal_sender, SIGUSR2) != 0) {
|
||||
debug("%u: %s", signal_sender, strerror(errno));
|
||||
}
|
||||
|
||||
debug("%s", "received remote control message");
|
||||
|
||||
pv_state_format_string_set(state, NULL);
|
||||
pv_state_name_set(state, NULL);
|
||||
pv_state_extra_display_set(state, NULL);
|
||||
|
||||
msgbuf.name[sizeof(msgbuf.name) - 1] = '\0';
|
||||
msgbuf.format[sizeof(msgbuf.format) - 1] = '\0';
|
||||
msgbuf.extra_display[sizeof(msgbuf.extra_display) - 1] = '\0';
|
||||
|
||||
pv_state_name_set(state, '\0' == msgbuf.name[0] ? NULL : msgbuf.name);
|
||||
|
||||
format_options.progress = msgbuf.progress;
|
||||
format_options.timer = msgbuf.timer;
|
||||
format_options.eta = msgbuf.eta;
|
||||
format_options.fineta = msgbuf.fineta;
|
||||
format_options.rate = msgbuf.rate;
|
||||
format_options.average_rate = msgbuf.average_rate;
|
||||
format_options.bytes = msgbuf.bytes;
|
||||
format_options.bufpercent = msgbuf.bufpercent;
|
||||
format_options.lastwritten = msgbuf.lastwritten;
|
||||
|
||||
pv_state_set_format_options(state, format_options);
|
||||
|
||||
if (msgbuf.rate_limit_specified)
|
||||
pv_state_rate_limit_set(state, msgbuf.rate_limit, msgbuf.rate_limit_specified,
|
||||
msgbuf.rate_limit_active);
|
||||
if (msgbuf.buffer_size > 0) {
|
||||
pv_state_target_buffer_size_set(state, msgbuf.buffer_size);
|
||||
}
|
||||
if (msgbuf.size > 0)
|
||||
pv_state_size_set(state, msgbuf.size);
|
||||
if (msgbuf.interval > 0)
|
||||
pv_state_interval_set(state, msgbuf.interval);
|
||||
if (msgbuf.width > 0 && msgbuf.width_set_manually)
|
||||
pv_state_width_set(state, msgbuf.width, msgbuf.width_set_manually);
|
||||
if (msgbuf.height > 0 && msgbuf.height_set_manually)
|
||||
pv_state_height_set(state, msgbuf.height, msgbuf.height_set_manually);
|
||||
if (msgbuf.format[0] != '\0')
|
||||
pv_state_format_string_set(state, msgbuf.format);
|
||||
if (msgbuf.extra_display[0] != '\0')
|
||||
pv_state_extra_display_set(state, msgbuf.extra_display);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for a --query message (SIGUSR1).
|
||||
*
|
||||
* If a type 0 message was received (query), then write a type 1 message
|
||||
* (response) to the control file and send a SIGUSR1 to the sending process.
|
||||
*
|
||||
* If a type 1 message was received (response), update the state from the
|
||||
* message in the control file.
|
||||
*
|
||||
* In both cases, the receiver of the message deletes its control file.
|
||||
*
|
||||
* The state transferred by message is transfer.elapsed_seconds,
|
||||
* transfer.transferred, and control.size.
|
||||
*
|
||||
* Returns true if a signal was received and dealt with, false otherwise.
|
||||
*
|
||||
* If match_sender is not zero, then ignores the signal and returns false if
|
||||
* the sending PID is not match_sender.
|
||||
*/
|
||||
static bool pv__rxsignal_usr1(pvstate_t state, pid_t match_sender)
|
||||
{
|
||||
pid_t signal_sender;
|
||||
char control_filename[4096]; /* flawfinder: ignore */
|
||||
FILE *control_fptr;
|
||||
struct query_msg msgbuf;
|
||||
|
||||
/* flawfinder rationale: as above. */
|
||||
|
||||
/*
|
||||
* Return early if a SIGUSR1 signal has not been received.
|
||||
*/
|
||||
signal_sender = 0;
|
||||
if (!pv_sigusr1_received(state, &signal_sender))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If match_sender was specified, ignore the signal if the sender
|
||||
* doesn't match.
|
||||
*/
|
||||
if ((0 != match_sender) && (signal_sender != match_sender)) {
|
||||
debug("%s=%d, %s=%d - %s", "match_sender", match_sender, "signal_sender", signal_sender,
|
||||
"ignoring USR1");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that errors are only reported with debug() rather than
|
||||
* pv_error() here so that the display of a running pv doesn't get
|
||||
* interrupted by, for example, a querying pv being terminated.
|
||||
*/
|
||||
|
||||
memset(control_filename, 0, sizeof(control_filename));
|
||||
control_fptr = pv_open_controlfile(control_filename, sizeof(control_filename), signal_sender, SIGUSR1, false);
|
||||
if (NULL == control_fptr) {
|
||||
debug("%s: %s", control_filename, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the message buffer from the remote control file, close it,
|
||||
* and delete it.
|
||||
*/
|
||||
if (1 != fread(&msgbuf, sizeof(msgbuf), 1, control_fptr)) {
|
||||
debug("fread: %s", strerror(errno));
|
||||
(void) fclose(control_fptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 != fclose(control_fptr)) {
|
||||
debug("fclose: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
debug("%s: %s", "removing", control_filename);
|
||||
if (0 != remove(control_filename)) {
|
||||
debug("remove: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (msgbuf.response) {
|
||||
/* Response message - update local state. */
|
||||
debug("%s: %d [%Lg, %ld, %ld]", "query response received", signal_sender, msgbuf.elapsed_seconds,
|
||||
msgbuf.transferred, msgbuf.size);
|
||||
state->transfer.elapsed_seconds = msgbuf.elapsed_seconds;
|
||||
state->transfer.transferred = msgbuf.transferred;
|
||||
state->control.size = msgbuf.size;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Query message - transmit state to sender. */
|
||||
|
||||
debug("%s: %d", "query received", signal_sender);
|
||||
|
||||
msgbuf.elapsed_seconds = state->transfer.elapsed_seconds;
|
||||
msgbuf.transferred = state->transfer.transferred;
|
||||
msgbuf.size = state->control.size;
|
||||
msgbuf.response = true;
|
||||
|
||||
memset(control_filename, 0, sizeof(control_filename));
|
||||
control_fptr = pv_open_controlfile(control_filename, sizeof(control_filename), (pid_t) getpid(), SIGUSR1, true);
|
||||
if (NULL == control_fptr) {
|
||||
debug("%s", strerror(errno));
|
||||
return true; /* true since the signal was received. */
|
||||
}
|
||||
|
||||
if (1 != fwrite(&msgbuf, sizeof(msgbuf), 1, control_fptr)) {
|
||||
debug("fwrite: %s", strerror(errno));
|
||||
(void) fclose(control_fptr);
|
||||
(void) remove(control_filename);
|
||||
return true; /* as above. */
|
||||
}
|
||||
|
||||
if (0 != fclose(control_fptr)) {
|
||||
debug("fclose: %s", strerror(errno));
|
||||
(void) remove(control_filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a SIGUSR1 signal to the remote process, to tell it this
|
||||
* query response message is ready to read.
|
||||
*/
|
||||
if (kill((pid_t) (signal_sender), SIGUSR1) != 0) {
|
||||
debug("%u: %s", signal_sender, strerror(errno));
|
||||
(void) remove(control_filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
debug("%s: %d", "query response sent", signal_sender);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for remote control messages. For a SIGUSR2 (--remote), replace the
|
||||
* current process's options with those being passed in. For a SIGUSR1
|
||||
* (--query), either receive transfer state from the sending process, or
|
||||
* send the current transfer state to the sending process, depending on the
|
||||
* content of the message.
|
||||
*
|
||||
* NB --remote relies on pv_state_set_format_options() causing the output
|
||||
* format to be reparsed.
|
||||
*
|
||||
* Returns true if a --remote message was received, false otherwise.
|
||||
*/
|
||||
bool pv_remote_check(pvstate_t state)
|
||||
{
|
||||
bool received_remote;
|
||||
|
||||
received_remote = pv__rxsignal_usr2(state);
|
||||
(void) pv__rxsignal_usr1(state, 0);
|
||||
|
||||
return received_remote;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Replace the transfer state with that of the given process, including the
|
||||
* total transfer size. If sizeptr is not NULL, the size is also copied to
|
||||
* *sizeptr (this is so a caller can get the size without knowing the
|
||||
* structure of pvstate_t).
|
||||
*
|
||||
* Returns nonzero on error. If "silent" is false, reports the error.
|
||||
*/
|
||||
int pv_remote_transferstate_fetch(pvstate_t state, pid_t query, /*@null@ */ off_t *sizeptr, bool silent)
|
||||
{
|
||||
char control_filename[4096]; /* flawfinder: ignore */
|
||||
FILE *control_fptr;
|
||||
struct query_msg msgbuf;
|
||||
pid_t signal_sender;
|
||||
long timeout;
|
||||
bool received;
|
||||
|
||||
/*
|
||||
* flawfinder rationale: buffer is large enough, explicitly zeroed,
|
||||
* and always bounded properly, as only pv_snprintf() writes to it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check that the remote process exists.
|
||||
*/
|
||||
if (kill((pid_t) (query), 0) != 0) {
|
||||
if (!silent)
|
||||
pv_perror("%s %u", _("pid"), query);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/* Set up the query message. */
|
||||
memset(&msgbuf, 0, sizeof(msgbuf));
|
||||
msgbuf.response = false;
|
||||
|
||||
/*
|
||||
* Get the filename and file stream to use.
|
||||
*/
|
||||
memset(control_filename, 0, sizeof(control_filename));
|
||||
control_fptr = pv_open_controlfile(control_filename, sizeof(control_filename), (pid_t) getpid(), SIGUSR1, true);
|
||||
if (NULL == control_fptr) {
|
||||
if (!silent)
|
||||
pv_perror("%s", control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the message to the control file, and close it.
|
||||
*/
|
||||
if (1 != fwrite(&msgbuf, sizeof(msgbuf), 1, control_fptr)) {
|
||||
if (!silent)
|
||||
pv_perror("%s", control_filename);
|
||||
(void) fclose(control_fptr);
|
||||
(void) remove(control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
if (0 != fclose(control_fptr)) {
|
||||
if (!silent)
|
||||
pv_perror("%s", control_filename);
|
||||
(void) remove(control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear this process's "SIGUSR1 received" flag and send a SIGUSR1
|
||||
* signal to the remote process, to tell it a query message is
|
||||
* ready.
|
||||
*/
|
||||
signal_sender = 0;
|
||||
(void) pv_sigusr1_received(state, &signal_sender);
|
||||
if (kill((pid_t) (query), SIGUSR1) != 0) {
|
||||
if (!silent)
|
||||
pv_perror("%s %u", _("pid"), query);
|
||||
(void) remove(control_filename);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
debug("%s: %d", "query sent", query);
|
||||
|
||||
/*
|
||||
* Wait for a SIGUSR1 signal to be sent back with a query response
|
||||
* message.
|
||||
*/
|
||||
|
||||
timeout = 1100000;
|
||||
received = false;
|
||||
|
||||
while (timeout > 10000 && !received && 0 == state->flags.trigger_exit) {
|
||||
struct timeval tv;
|
||||
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
/*@-nullpass@ *//* splint: NULL is OK with select() */
|
||||
(void) select(0, NULL, NULL, NULL, &tv);
|
||||
/*@+nullpass@ */
|
||||
timeout -= 10000;
|
||||
|
||||
if (pv__rxsignal_usr1(state, query)) {
|
||||
debug("%s", "response received");
|
||||
received = true;
|
||||
if (NULL != sizeptr)
|
||||
*sizeptr = state->control.size;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the control file in case it still exists - the other
|
||||
* process should have removed it.
|
||||
*/
|
||||
debug("%s: %s", "cleaning up", control_filename);
|
||||
(void) remove(control_filename);
|
||||
|
||||
/*
|
||||
* Return 0 if the message was received.
|
||||
*/
|
||||
if (received)
|
||||
return 0;
|
||||
|
||||
/*@-mustfreefresh@ */
|
||||
/*
|
||||
* splint note: the gettext calls made by _() cause memory leak
|
||||
* warnings, but in this case it's unavoidable, and mitigated by the
|
||||
* fact that each string is only translated once.
|
||||
*/
|
||||
if (!silent)
|
||||
pv_error("%u: %s", query, _("message not received"));
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
/*@+mustfreefresh @ */
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else /* !PV_REMOTE_CONTROL */
|
||||
|
||||
/*
|
||||
* Dummy stubs for remote control when PV_REMOTE_CONTROL is not set.
|
||||
*/
|
||||
|
||||
bool pv_remote_check( /*@unused@ */ __attribute__((unused)) pvstate_t state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int pv_remote_set( /*@unused@ */
|
||||
__attribute__((unused)) pvstate_t state, /*@unused@ */ __attribute__((unused)) pid_t remote)
|
||||
{
|
||||
/*@-mustfreefresh@ *//* splint - see above */
|
||||
pv_error("%s", _("SA_SIGINFO not supported on this system"));
|
||||
/*@+mustfreefresh@ */
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
|
||||
int pv_remote_transferstate_fetch( /*@unused@ */
|
||||
__attribute__((unused)) pvstate_t state,
|
||||
/*@unused@ */
|
||||
__attribute__((unused)) pid_t query,
|
||||
/*@null@ */
|
||||
/*@unused@ */
|
||||
__attribute__((unused)) off_t *sizeptr,
|
||||
/*@unused@ */
|
||||
__attribute__((unused))
|
||||
bool silent)
|
||||
{
|
||||
/*@-mustfreefresh@ *//* splint - see above */
|
||||
pv_error("%s", _("SA_SIGINFO not supported on this system"));
|
||||
/*@+mustfreefresh@ */
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
#endif /* PV_REMOTE_CONTROL */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user