Commit Graph
96 Commits
Author SHA1 Message Date
Igor Anić e831313b10 std.io: remove BufferedTee
Introduced in  #19032 as a fix for #18967.
Not needed any more after #19253.
2024-03-20 21:05:35 -07:00
Igor Anić 3ea1276eeb io_uring: ring mapped buffers (#17806)
* io_uring: ring mapped buffers

Ring mapped buffers are newer implementation of ring provided buffers, supported
since kernel 5.19. Best described in Jens Axboe [post](https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023#provided-buffers)

This commit implements low level io_uring_*_buf_ring_* functions as mostly
direct translation from liburing. It also adds BufferGroup abstraction over those
low level functions.

* io_uring: add multishot recv to BufferGroup

Once we have ring mapped provided buffers functionality it is possible to use
multishot recv operation. Multishot receive is submitted once, and completions
are posted whenever data arrives on the socket. Received data are placed in a
new buffer from buffer group.

Reference: [io_uring and networking in 2023](https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023#multi-shot)

Getting NOENT for cancel completion result, meaning:
  -ENOENT
    The request identified by user_data could not be located.
    This could be because it completed before the cancelation
    request was issued, or if an invalid identifier is used.

https://man7.org/linux/man-pages/man3/io_uring_prep_cancel.3.html
https://github.com/ziglang/zig/actions/runs/6801394000/job/18492139893?pr=17806

Result in cancel/recv cqes are different depending on the kernel.
on older kernel (tested with v6.0.16, v6.1.57, v6.2.12, v6.4.16)
  cqe_cancel.err() == .NOENT
  cqe_crecv.err() == .NOBUFS
on kernel (tested with v6.5.0, v6.5.7)
  cqe_cancel.err() == .SUCCESS
  cqe_crecv.err() == .CANCELED
2024-03-15 22:34:31 -04:00
Igor Anić 791c4491a7 compress.xz: remove unnecessary variable
`to_read.items.len is always zero when entering readBlock.
2024-03-13 18:43:36 +01:00
Igor Anić 54f882c4aa compress.xz: make reader loop little more readable
No need to do same error check on two places. First return all
uncompressed data then on last read check error.
2024-03-13 18:41:20 +01:00
Igor Anić a21f9b6d8b compress.xz: remove copyForwards from tight loop
In the example from the issue #19052 to_read holds 213_315_584
uncompressed bytes. Calling read with small output results in many
shifts of that big buffer.
This removes need to shift to_read after each read.
2024-03-13 18:22:08 +01:00
Igor Anić f8f43ca3e1 package: remove git fetch zlib lookahead fix
My first zlib implementation broke git fetch because it introduce
[lookahead](https://github.com/ziglang/zig/issues/18967). That resulted
in workarounds [1](https://github.com/ziglang/zig/commit/80f3ef6e14a1213d1c3b31d515870afb43cc9379)
[2](https://github.com/ziglang/zig/commit/d00faa2407cdeaa058da62f2d95f64f9e7ed6a09)

After [fixing](https://github.com/ziglang/zig/pull/19163) lookahead in
zlib decompressor this fixes are no longer necessary.
2024-03-11 16:49:21 -07:00
Igor Anić c974e19816 docs: make docs work with recent tar changes
It is no longer need to call skip if file content is not consumed. It is
handled internally now. File types are now same as in os.File.
2024-03-11 13:30:26 +01:00
Igor Anić 0cca7e732e std.tar: fix broken public interface 2024-03-11 12:25:51 +01:00
Igor Anić c4868b2bbc std.tar: use doctest
Make std.tar look better in docs. Remove from public interface what is
not necessary. Add comment to the public methods. Add doctest as usage
examples for iterator and pipeToFileSystem.
2024-03-11 12:25:03 +01:00
Igor Anić a9e7abda20 std.tar: fix test hanging on windows
Problem was manifested only on windows with target `-target
aarch64-windows-gnu`.

I was creating new files but not closing any of them. Tmp dir cleanup
hangs looping in deleteTree forever.
2024-03-11 12:24:11 +01:00
Igor Anić 8ec990d6d7 disable test which is hanging on windows in ci
When this test is enabled something like:
`zig build test docs --zig-lib-dir .\lib\ -Dstatic-llvm -Dskip-non-native -Denable-symlinks-windows`
never finishes.

Those are failed runs from ci:
https://github.com/ziglang/zig/actions/runs/8137710393
https://github.com/ziglang/zig/actions/runs/8129619923
https://github.com/ziglang/zig/actions/runs/8125845128

Isolating that test and running it is not a problem. Running something
like `zig test .\lib\std\std.zig  --zig-lib-dir .\lib\` is fine.
2024-03-11 12:24:11 +01:00
Igor Anić 8cc35a0255 std.tar: fix path testing on windows
Fixing ci error: error:

'tar.test.test.pipeToFileSystem' failed: slices differ. first difference occurs at index 2 (0x2)

============ expected this output: =============  len: 9 (0x9)

2E 2E 2F 61 2F 66 69 6C  65                       ../a/file

============= instead found this: ==============  len: 9 (0x9)

2E 2E 5C 61 5C 66 69 6C  65                       ..\a\file

After #19136 dir.symlink changes path separtors to \ on windows.
2024-03-11 12:24:11 +01:00
Igor Anić 67336ca8c6 std.tar: fix build on 32 bit platform
Fixing error from ci:

std/tar.zig:423:54: error: expected type 'usize', found 'u64'
std/tar.zig:423:54: note: unsigned 32-bit int cannot represent all possible unsigned 64-bit values
2024-03-11 12:24:11 +01:00
Igor Anić f5fd4691e5 std.tar: document iterator interface with example 2024-03-11 12:24:06 +01:00
Igor Anić 614161a7cf std.tar make iterator interface more ergonomic
for the then end users:

1. Don't require user to call file.skip() on file returned from
iterator.next if file is not read. Iterator will now handle this.
Previously that returned header parsing error, without knowing some tar
internals it is hard to understand what is required from user.

2. Use iterator.File.kind enum which is similar to fs.File.Kind,
something familiar. Internal Header.Kind has many types which are not
exposed but the user needs to have else in kind switch to cover those
cases.

3. Add reader interface to the iterator.File.
2024-03-11 12:22:12 +01:00
Igor Anić 5ccbb196ad std.tar: don't return in iterator init
Don't assert min buffer size on iterator init. That was changing public
interface. This way we don't break that interface.
2024-03-11 12:22:12 +01:00
Igor Anić 10add7c677 std.tar: remove redundant test name prefixes 2024-03-11 12:22:12 +01:00
Igor Anić 04e8bbd932 std.tar: test buffers provided to the iterator
Tar header stores name in max 256 bytes and link name in max 100 bytes.
Those are minimums for provided buffers. Error is raised during iterator
init if buffers are not long enough.

Pax and gnu extensions can store longer names. If such extension is
reached during unpack and don't fit into provided buffer error is
returned.
2024-03-11 12:22:12 +01:00
Igor Anić af0502f6c4 std.tar: add tests for file and symlink create
Should do that before I broke package manager!
2024-03-11 12:22:00 +01:00
Igor Anić a06a305f97 zlib: fix missing comptime attribute 2024-03-04 09:53:01 +01:00
Igor Anić c680b5d138 compress.zlib: add overshoot test cast
Using example from [zigimg](https://github.com/zigimg/zigimg/pull/164) project.
2024-03-04 09:53:01 +01:00
Igor Anić f2508abfa6 flate: use 4 bytes lookahead for zlib
That ensures no bytes are left in the BitReader buffer after we reach
end of the stream.
2024-03-04 09:53:01 +01:00
Igor Anić 711281602a flate: option to fill BitReader
fill(0) will fill all bytes in bit reader. If bit reader is aligned to
the byte, as it is at the end of the stream this ensures no overshoot
when reading footer. Footer is 4 bytes (zlib) or 8 bytes (gzip). For
zlib we will use 4 bytes BitReader and 8 for gzip. After align and fill
we will read those bytes and leave BitReader empty after that.
2024-03-04 09:53:01 +01:00
Igor Anić 8a963fd66e flate: 32 bit BitReader
Extend BitReader to accept size of internal buffer. It can be u64 (only
option until now) or u32.
2024-03-04 09:53:01 +01:00
Igor Anić e57800610b std.tar: disable test failing on windows
Just to pass ci of regression fix #19126.
I'll return to this later.
Currently can't reproduce on my Windows wm, here I'm failing on symlink creation
in ci fails later in the process.
2024-02-29 07:57:49 +01:00
Igor Anić 7d536e8970 std.tar: fix unconditional error return 2024-02-29 01:22:49 +01:00
Igor Anić 62ce753814 compress: activate tests in wasm32
They were disabled because insufficient stack size.
That is
[changed](https://github.com/ziglang/zig/commit/d51aa9748f9e4e3616328a207a8047ff37d81f8b) now.
2024-02-27 19:19:59 -08:00
Igor Anić 65e5c46d61 std.tar fix refactored function
It was not returning error in all cases. Bug in refactoring.
2024-02-26 00:24:23 +01:00
Igor Anić f086ea856c std.tar skip test on windows
Or other platform which don't support symlinks.
2024-02-25 15:57:20 +01:00
Igor Anić 30a319be6d std.tar improve error reporting
Report file name which failed to create in all cases.
2024-02-25 12:03:23 +01:00
Igor Anić 96e4d56819 std.tar add case sensitive file name test
Like in issue #18089, this tar contains, same file name in two case
sensitive name version. Unpack should fail on case insensitive file
systems and succeed on case sensitive.

$ tar tvf 18089.tar
    18089/
    18089/alacritty/
    18089/alacritty/darkermatrix.yml
    18089/alacritty/Darkermatrix.yml
2024-02-25 10:35:18 +01:00
Igor Anić b84301c8e5 std.tar don't overwrite existing file
Fail with error if file already exists. File is not silently overwritten
but an error is raised.

Fixes: #18089
2024-02-24 23:37:55 +01:00
Igor Anić 8d651f512b std.tar fix assert exploited by fuzzing 2024-02-24 13:17:04 -08:00
Igor Anić 0a86b117bf std.tar fix integer overflow in header size parse
Found by fuzzing. Fixing code and adding test.
2024-02-23 21:57:40 +01:00
Igor Anić f67aa8b9b3 std.tar fix parsing mode field in tar header
Found by fuzzing. Previous numeric function assumed that is is getting
buffer of size 12, mode is size 8. Fuzzing found overflow.
Fixing and adding test cases.
2024-02-23 21:57:15 +01:00
Igor Anić 30f15e3afe fix crash in tar found by fuzzing
Running fuzzing tar test with [zig std lib
fuzzing](https://github.com/squeek502/zig-std-lib-fuzzing) reached and
assert in tar implementation. Assert (in std lib) should not be
reachable by external input, so I'm fixing this to return error.
2024-02-22 18:20:05 -08:00
Igor Anić a5326c5ef8 return few previous fixes
Review: https://github.com/ziglang/zig/pull/19032#pullrequestreview-1896251841
2024-02-22 17:20:41 +01:00
Igor Anić d00faa2407 use BufferedTee in Fetch/git.zig 2024-02-22 15:18:03 +01:00
Igor Anić eb67fab2d9 refactor according to Ian's review
https://github.com/ziglang/zig/pull/19032#pullrequestreview-1894702793
2024-02-22 12:29:21 +01:00
Igor Anić ce1a590fc9 cleanup tests 2024-02-21 20:26:29 +01:00
Igor Anić d995029844 add BufferedTee
BufferedTee provides reader interface to the consumer. Data read by consumer
is also written to the output. Output is hold lookahead_size bytes behind
consumer. Allowing consumer to put back some bytes to be read again. On flush
all consumed bytes are flushed to the output.

      input   ->   tee   ->   consumer
                    |
                 output

input - underlying unbuffered reader
output - writer, receives data read by consumer
consumer - uses provided reader interface

If lookahead_size is zero output always has same bytes as consumer.
2024-02-21 20:01:45 +01:00
Igor Anić 3e8cb153ea fix flate regression
Until now literal and distance code lengths where treated as two
different arrays. But according to rfc they can overlap:

  The code length repeat codes can cross from HLIT + 257 to the
  HDIST + 1 code lengths.  In other words, all code lengths form
  a single sequence of HLIT + HDIST + 258 values.

Now code lengths are decoded in single array which is then split
to literal and distance part.
2024-02-17 15:31:13 -08:00
Igor Anić 99cb201438 skip failing wasm tests 2024-02-15 00:35:08 +01:00
Igor Anić fd9db4962c reorganize compress package root folder 2024-02-14 23:34:13 +01:00
Igor Anić 2457b68b2f remove v1 deflate implementation 2024-02-14 22:34:13 +01:00
Igor Anić e20080be13 preserve valuable tests from v1 implementation
Before removal of v1.
2024-02-14 22:12:54 +01:00
Igor Anić 0afe808928 remove testing struct sizes
It was usefull during development.

From andrewrk code review comment:
In fact, Zig does not guarantee the @sizeOf structs, and so these tests are not valid.
2024-02-14 21:06:45 +01:00
Igor Anić d49cdf5b2d skip calculating struct sizes on 32 bit platforms 2024-02-14 19:58:45 +01:00
Igor Anić c2361bf548 fix top level docs comments
I didn't understand the difference.

ref: https://ziglang.org/documentation/0.11.0/#Comments
2024-02-14 18:28:20 +01:00
Igor Anić 5fbc371b41 fix wording in comment 2024-02-14 18:28:20 +01:00
Igor Anić f81b3a2095 fix reading input stream during decompression
By using read instead of readAll decompression reader could get bytes
then available in the stream and then later wrongly failed with end of
stream.
2024-02-14 18:28:20 +01:00
Igor Anić 0cba50d73e set testdata as binary
Testing on windows is failing because line ending are changed on some
binary files during git checkout.
2024-02-14 18:28:20 +01:00
Igor Anić d645114f7e add deflate implemented from first principles
Zig deflate compression/decompression implementation. It supports compression and decompression of gzip, zlib and raw deflate format.

Fixes #18062.

This PR replaces current compress/gzip and compress/zlib packages. Deflate package is renamed to flate. Flate is common name for deflate/inflate where deflate is compression and inflate decompression.

There are breaking change. Methods signatures are changed because of removal of the allocator, and I also unified API for all three namespaces (flate, gzip, zlib).

Currently I put old packages under v1 namespace they are still available as compress/v1/gzip, compress/v1/zlib, compress/v1/deflate. Idea is to give users of the current API little time to postpone analyzing what they had to change. Although that rises question when it is safe to remove that v1 namespace.

Here is current API in the compress package:

```Zig
// deflate
    fn compressor(allocator, writer, options) !Compressor(@TypeOf(writer))
    fn Compressor(comptime WriterType) type

    fn decompressor(allocator, reader, null) !Decompressor(@TypeOf(reader))
    fn Decompressor(comptime ReaderType: type) type

// gzip
    fn compress(allocator, writer, options) !Compress(@TypeOf(writer))
    fn Compress(comptime WriterType: type) type

    fn decompress(allocator, reader) !Decompress(@TypeOf(reader))
    fn Decompress(comptime ReaderType: type) type

// zlib
    fn compressStream(allocator, writer, options) !CompressStream(@TypeOf(writer))
    fn CompressStream(comptime WriterType: type) type

    fn decompressStream(allocator, reader) !DecompressStream(@TypeOf(reader))
    fn DecompressStream(comptime ReaderType: type) type

// xz
   fn decompress(allocator: Allocator, reader: anytype) !Decompress(@TypeOf(reader))
   fn Decompress(comptime ReaderType: type) type

// lzma
    fn decompress(allocator, reader) !Decompress(@TypeOf(reader))
    fn Decompress(comptime ReaderType: type) type

// lzma2
    fn decompress(allocator, reader, writer !void

// zstandard:
    fn DecompressStream(ReaderType, options) type
    fn decompressStream(allocator, reader) DecompressStream(@TypeOf(reader), .{})
    struct decompress
```

The proposed naming convention:
 - Compressor/Decompressor for functions which return type, like Reader/Writer/GeneralPurposeAllocator
 - compressor/compressor for functions which are initializers for that type, like reader/writer/allocator
 - compress/decompress for one shot operations, accepts reader/writer pair, like read/write/alloc

```Zig
/// Compress from reader and write compressed data to the writer.
fn compress(reader: anytype, writer: anytype, options: Options) !void

/// Create Compressor which outputs the writer.
fn compressor(writer: anytype, options: Options) !Compressor(@TypeOf(writer))

/// Compressor type
fn Compressor(comptime WriterType: type) type

/// Decompress from reader and write plain data to the writer.
fn decompress(reader: anytype, writer: anytype) !void

/// Create Decompressor which reads from reader.
fn decompressor(reader: anytype) Decompressor(@TypeOf(reader)

/// Decompressor type
fn Decompressor(comptime ReaderType: type) type

```

Comparing this implementation with the one we currently have in Zig's standard library (std).
Std is roughly 1.2-1.4 times slower in decompression, and 1.1-1.2 times slower in compression. Compressed sizes are pretty much same in both cases.
More resutls in [this](https://github.com/ianic/flate) repo.

This library uses static allocations for all structures, doesn't require allocator. That makes sense especially for deflate where all structures, internal buffers are allocated to the full size. Little less for inflate where we std version uses less memory by not preallocating to theoretical max size array which are usually not fully used.

For deflate this library allocates 395K while std 779K.
For inflate this library allocates 74.5K while std around 36K.

Inflate difference is because we here use 64K history instead of 32K in std.

If merged existing usage of compress gzip/zlib/deflate need some changes. Here is example with necessary changes in comments:

```Zig

const std = @import("std");

// To get this file:
// wget -nc -O war_and_peace.txt https://www.gutenberg.org/ebooks/2600.txt.utf-8
const data = @embedFile("war_and_peace.txt");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer std.debug.assert(gpa.deinit() == .ok);
    const allocator = gpa.allocator();

    try oldDeflate(allocator);
    try new(std.compress.flate, allocator);

    try oldZlib(allocator);
    try new(std.compress.zlib, allocator);

    try oldGzip(allocator);
    try new(std.compress.gzip, allocator);
}

pub fn new(comptime pkg: type, allocator: std.mem.Allocator) !void {
    var buf = std.ArrayList(u8).init(allocator);
    defer buf.deinit();

    // Compressor
    var cmp = try pkg.compressor(buf.writer(), .{});
    _ = try cmp.write(data);
    try cmp.finish();

    var fbs = std.io.fixedBufferStream(buf.items);
    // Decompressor
    var dcp = pkg.decompressor(fbs.reader());

    const plain = try dcp.reader().readAllAlloc(allocator, std.math.maxInt(usize));
    defer allocator.free(plain);
    try std.testing.expectEqualSlices(u8, data, plain);
}

pub fn oldDeflate(allocator: std.mem.Allocator) !void {
    const deflate = std.compress.v1.deflate;

    // Compressor
    var buf = std.ArrayList(u8).init(allocator);
    defer buf.deinit();
    // Remove allocator
    // Rename deflate -> flate
    var cmp = try deflate.compressor(allocator, buf.writer(), .{});
    _ = try cmp.write(data);
    try cmp.close(); // Rename to finish
    cmp.deinit(); // Remove

    // Decompressor
    var fbs = std.io.fixedBufferStream(buf.items);
    // Remove allocator and last param
    // Rename deflate -> flate
    // Remove try
    var dcp = try deflate.decompressor(allocator, fbs.reader(), null);
    defer dcp.deinit(); // Remove

    const plain = try dcp.reader().readAllAlloc(allocator, std.math.maxInt(usize));
    defer allocator.free(plain);
    try std.testing.expectEqualSlices(u8, data, plain);
}

pub fn oldZlib(allocator: std.mem.Allocator) !void {
    const zlib = std.compress.v1.zlib;

    var buf = std.ArrayList(u8).init(allocator);
    defer buf.deinit();

    // Compressor
    // Rename compressStream => compressor
    // Remove allocator
    var cmp = try zlib.compressStream(allocator, buf.writer(), .{});
    _ = try cmp.write(data);
    try cmp.finish();
    cmp.deinit(); // Remove

    var fbs = std.io.fixedBufferStream(buf.items);
    // Decompressor
    // decompressStream => decompressor
    // Remove allocator
    // Remove try
    var dcp = try zlib.decompressStream(allocator, fbs.reader());
    defer dcp.deinit(); // Remove

    const plain = try dcp.reader().readAllAlloc(allocator, std.math.maxInt(usize));
    defer allocator.free(plain);
    try std.testing.expectEqualSlices(u8, data, plain);
}

pub fn oldGzip(allocator: std.mem.Allocator) !void {
    const gzip = std.compress.v1.gzip;

    var buf = std.ArrayList(u8).init(allocator);
    defer buf.deinit();

    // Compressor
    // Rename compress => compressor
    // Remove allocator
    var cmp = try gzip.compress(allocator, buf.writer(), .{});
    _ = try cmp.write(data);
    try cmp.close(); // Rename to finisho
    cmp.deinit(); // Remove

    var fbs = std.io.fixedBufferStream(buf.items);
    // Decompressor
    // Rename decompress => decompressor
    // Remove allocator
    // Remove try
    var dcp = try gzip.decompress(allocator, fbs.reader());
    defer dcp.deinit(); // Remove

    const plain = try dcp.reader().readAllAlloc(allocator, std.math.maxInt(usize));
    defer allocator.free(plain);
    try std.testing.expectEqualSlices(u8, data, plain);
}

```
2024-02-14 18:28:20 +01:00
Igor Anić 7d3a31872e tar: improve diagnostic reporting
Using Python testtar file (mentioned in #14310) to test diagnostic
reporting.
Added computing checksum by using both unsigned and signed header bytes
values.
Added skipping gnu exteneded sparse headers while reporting unsupported
header in diagnostic.

Note on testing:

wget https://github.com/python/cpython/raw/3.11/Lib/test/testtar.tar -O
/tmp/testtar.tar

```
test "Python testtar.tar file" {
    const file_name = "testtar.tar";

    var file = try std.fs.cwd().openFile("/tmp/" ++ file_name, .{});
    defer file.close();

    var diag = Options.Diagnostics{ .allocator = std.testing.allocator };
    defer diag.deinit();

    var iter = iterator(file.reader(), &diag);
    while (try iter.next()) |f| {
        std.debug.print("supported: {} {s} {d}\n", .{ f.kind, f.name, f.size });
        try f.skip();
    }
    for (diag.errors.items) |e| {
        switch (e) {
            .unsupported_file_type => |u| {
                std.debug.print("unsupported: {} {s}\n", .{ u.file_type, u.file_name });
            },
            else => unreachable,
        }
    }
}
```
2024-01-13 19:37:33 -07:00
Igor Anić 7923a53996 tar: rename reader to iterator
Itarator has `next` function, iterates over tar files. When using from
outside of module with `tar.` prefix makes more sense.

var iter = tar.iterator(reader, null);
while (try iter.next()) |file| {
...
}
2024-01-13 19:37:33 -07:00
Igor Anić e21a12e56b tar: use @embedFile in tests
Like in other tests which uses testdata files (compress). That enables
wasi testing also, was failing because file system operations in tests.
2024-01-13 19:37:33 -07:00
Igor Anić 76fe1f53d5 tar: fix tests on 32-bit platforms 2024-01-13 19:37:33 -07:00
Igor Anić a75fd4ff15 tar: move test cases to std/tar/testdata
Create std/tar/test.zig for test which uses cases from testdata.
2024-01-13 19:37:33 -07:00
Igor Anić f8e42d6b30 tar: add Go test case files to the project 2024-01-13 19:37:33 -07:00
Igor Anić c07527abac tar: reorganize file, functions before tests 2024-01-13 19:37:33 -07:00
Igor Anić c76abe0e18 tar: use file word in less places 2024-01-13 19:37:33 -07:00
Igor Anić 4a6d67ab1a tar: remove stratch from tar reader
Use explicit buffers for name, link_name instead.
It is cleaner that way.
2024-01-13 19:37:33 -07:00
Igor Anić 9f7dd32308 tar: refactor pax attribute
Make it little readable.
2024-01-13 19:37:33 -07:00
Igor Anić dbab45cfc6 tar: replace custom buffered reader with std.io 2024-01-13 19:37:33 -07:00
Igor Anić 58e0e509c6 tar: add module comment and references 2024-01-13 19:37:33 -07:00
Igor Anić a3cf8ec71e tar: add pax file reader tests 2024-01-13 19:37:33 -07:00
Igor Anić 7b0bbc680f tar: add file mode to result of tarbal iteration
So we have information to set executable bit on write to file system.
2024-01-13 19:37:33 -07:00
Igor Anić 2a432d3008 tar: prefix test cases with 'tar'
To make it little easier to filter from all stdlib tests.
2024-01-13 19:37:33 -07:00
Igor Anić 2ed9a276a7 tar: use Go test cases path from env variable
Skip tests if env is not set.
2024-01-13 19:37:33 -07:00
Igor Anić 6bfa7bf197 tar: use scratch buffer for file names
That makes names strings stable during the iteration. Otherwise string
buffers can be overwritten while reading file content.
2024-01-13 19:37:33 -07:00
Igor Anić 6e7a39c935 tar: refactor reading pax attributes 2024-01-13 19:37:33 -07:00
Igor Anić c761dfc176 tar: add gnu path and link extensions handling 2024-01-13 19:37:33 -07:00
Igor Anić 48b160c1bf tar: handle pax null attrs and pax attr ending 2024-01-13 19:37:33 -07:00
Igor Anić 16c40fc471 tar: add header chksum checking 2024-01-13 19:37:33 -07:00
Igor Anić 169f28d3e6 tar: fix import path 2024-01-13 19:37:33 -07:00
Igor Anić e1424b84b8 tar: add parsing size in gnu extended format
Reference:
https://www.gnu.org/software/tar/manual/html_node/Extensions.html#Extensions

If the leading byte is 0x80 (128), the non-leading bytes of the field
are concatenated in big-endian order, with the result being a positive
number expressed in binary form.
2024-01-13 19:37:33 -07:00
Igor Anić 6d5283e835 tar: refactor reader and iterator
Make it more readable.
2024-01-13 19:37:33 -07:00
Igor Anić be5d04ab79 tar: add pax linkpath attribute parsing
Name of symbolic link can be also found in pax attribute.
2024-01-13 19:37:33 -07:00
Igor Anić 1817063375 tar: add initial test cases
Just adding tests, without changing functionality.
2024-01-13 19:37:33 -07:00
Igor Anić 4381241237 tar: refactor Buffer
Move reader into Buffer and make it BufferedReader. This doesn't
introduce any new functionality just grouping similar things.
2024-01-13 19:37:33 -07:00
Igor Anić ff8544daa5 tar: refactor code to be more testable
Split reading/parsing tar file and writing results to the disk in two
separate steps. So we can later test parsing part without need to write
everyting to the disk.
2024-01-13 19:37:33 -07:00
Igor Anić be4a77d9aa io_uring: fix ci failing test
Getting this error in ci:
run test std-arm-linux-none-generic-Debug: error: 'test.accept/connect/send_zc/recv' failed: /home/ci/actions-runner1/_work/zig/zig/lib/std/os/linux/io_uring.zig:60:23: 0x70b06b in init_params (test)
            .NOSYS => return error.SystemOutdated,
                      ^
/home/ci/actions-runner1/_work/zig/zig/lib/std/os/linux/io_uring.zig:27:16: 0x70b6b7 in init (test)
        return try IO_Uring.init_params(entries, &params);
               ^
/home/ci/actions-runner1/_work/zig/zig/lib/std/os/linux/io_uring.zig:3807:16: 0x72405b in test.accept/connect/send_zc/recv (test)
    var ring = try IO_Uring.init(16, 0);

https://github.com/ziglang/zig/actions/runs/6909813408/job/18801841015?pr=18025
2023-11-18 05:40:24 +01:00
Igor Anić 7eee0d3353 io_uring: try to pass windows/macos tests 2023-11-17 23:39:29 +01:00
Igor Anić ccf5a6cc5c io_uring: make Linux version check runtime instead od comptime
Reverting previous change.
I'm building test bin and then running it in virtual machines with different
kernels. So Linux kernel checks has to be runtime instead of comptime.
2023-11-17 22:17:00 +01:00
Igor Anić a7001b86f1 io_uring: include review comments
Thanks @rootbeer for review.
This adds description to send_zc behavior.
Cleans up tests.
2023-11-17 19:58:23 +01:00
Igor Anić 257b8131ec io_uring: use kernel version test in send_zc test 2023-11-17 17:21:54 +01:00
Igor Anić 87dd8d5669 io_uring: simplify tests by checking kernel version
So far we relied on getting EINVAL in CQE for operations that kernel don't
support. The problem with that approach is that there are many other reasons
(like wrong params) to get EINVAL. The other problem is when we have an
operation that existed before and gets new behavior via different attributes,
like accept and accept_direct. Older kernels can fall back to non direct
operation although we set attributes for direct operation. Operation completes
successfully in both cases but with different results.

This commit introduces kernel version check at the start of the test. Making
body of the test free of checking for various kernel version differences.

Feature availability references:
  * https://manpages.debian.org/unstable/liburing-dev/io_uring_enter.2.en.html
  * https://kernel.dk/axboe-kr2022.pdf
  * https://github.com/Jiboo/zig/blob/5acf7969bc759ce51005924109924d9666f74429/lib/std/os/linux.zig#L3727
  * https://github.com/Jiboo/zig/blob/5acf7969bc759ce51005924109924d9666f74429/lib/std/os/linux.zig#L3993
2023-11-17 16:31:57 +01:00
Igor Anić 256384a2ec io_uring: add direct operations
Add operation on direct file descriptors. Also referred to as fixed or
registered files.

References:
https://kernel.dk/axboe-kr2022.pdf
https://lwn.net/Articles/863071/

Added functions:

IO_Uring
  accept_direct
  accept_multishot_direct
  openat_direct
  close_direct
  socket
  socket_direct
  socket_direct_alloc

Raw prepare operations:
  io_uring_prep_accept_direct
  io_uring_prep_multishot_accept_direct
  io_uring_prep_openat_direct
  io_uring_prep_close_direct
  io_uring_prep_socket
  io_uring_prep_socket_direct
  io_uring_prep_socket_direct_alloc

Tested on this kernels:

5.4.0-164-generic
2559 passed; 70 skipped; 0 failed.

5.8.0-63-generic
2573 passed; 56 skipped; 0 failed.

5.11.0-49-generic
2576 passed; 53 skipped; 0 failed.

5.13.0-52-generic
2576 passed; 53 skipped; 0 failed.

5.15.0-87-generic
2579 passed; 50 skipped; 0 failed.

5.19.0-46-geneic
2584 passed; 45 skipped; 0 failed.

6.2.0-35-generic.log
2585 passed; 44 skipped; 0 failed.

6.5.0-9-generic
2585 passed; 44 skipped; 0 failed.
2023-11-17 13:48:17 +01:00
Igor Anić 087ee497d4 io_uring: add zero-copy send operation
`send_zc` tries to avoid making intermediate copies of data. Zerocopy execution
is not guaranteed and may fall back to copying.

The flags field of the first struct io_uring_cqe may likely contain
IORING_CQE_F_MORE , which means that there will be a second completion event /
notification for the request, with the user_data field set to the same value.
The user must not modify the data buffer until the notification is posted. The
first cqe follows the usual rules and so its res field will contain the number
of bytes sent or a negative error code. The notification's res field will be set
to zero and the flags field will contain IORING_CQE_F_NOTIF. The two step model
is needed because the kernel may hold on to buffers for a long time, e.g.
waiting for a TCP ACK, and having a separate cqe for request completions allows
userspace to push more data without extra delays. Note, notifications are only
responsible for controlling the lifetime of the buffers, and as such don't mean
anything about whether the data has atually been sent out or received by the
other end. Even errored requests may generate a notification, and the user must
check for IORING_CQE_F_MORE rather than relying on the result.

Available since kernel 6.0.

References:
https://man7.org/linux/man-pages/man3/io_uring_prep_send_zc.3.html
https://man7.org/linux/man-pages/man2/io_uring_enter.2.html
2023-11-10 16:44:18 +01:00
Igor Anić 715e5f757f fix io_uring tests on kernel 5.4
Unsupported tests are now skipped on kernel 5.4:
```
uname -a
Linux d20 5.4.0-166-generic #183-Ubuntu SMP Mon Oct 2 11:31:37 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
zig test lib/std/std.zig --zig-lib-dir lib --main-mod-path lib/std 2>&1 | cat
709/2616 test.nop... OK
710/2616 test.readv... OK
711/2616 test.writev/fsync/readv... OK
712/2616 test.write/read... SKIP
713/2616 test.splice/read... SKIP
714/2616 test.write_fixed/read_fixed... OK
715/2616 test.openat... SKIP
716/2616 test.close... SKIP
717/2616 test.accept/connect/send/recv... SKIP
718/2616 test.sendmsg/recvmsg... OK
719/2616 test.timeout (after a relative time)... SKIP
720/2616 test.timeout (after a number of completions)... OK
721/2616 test.timeout_remove... SKIP
722/2616 test.accept/connect/recv/link_timeout... SKIP
723/2616 test.fallocate... SKIP
724/2616 test.statx... SKIP
725/2616 test.accept/connect/recv/cancel... SKIP
726/2616 test.register_files_update... SKIP
727/2616 test.shutdown... SKIP
728/2616 test.renameat... SKIP
729/2616 test.unlinkat... SKIP
730/2616 test.mkdirat... SKIP
731/2616 test.symlinkat... SKIP
732/2616 test.linkat... SKIP
733/2616 test.provide_buffers: read... SKIP
734/2616 test.remove_buffers... SKIP
735/2616 test.provide_buffers: accept/connect/send/recv... SKIP
736/2616 test.accept multishot... SKIP
```
2023-11-08 18:52:03 +01:00
Igor Anić 7a1dbbd4f9 fix io_uring timeout_remove test on kernel 5.4
There is no grantee that `copy_cqes` will return exactly wait_nr number of cqes.
If there are ready cqes it can return > 0 but < wait_nr number of cqes.
2023-11-08 18:25:29 +01:00
Igor Anić bec36aa7c0 io_uring: add multishot accept operation
Server networking application typically accept multiple connections. Multishot
accept simplifies handling these situations. Applications submits once and
receives CQE whenever a new connection request comes in.

Multishot is active until it is canceled or experience error. While active, and
further notification are expected CQE completion will have IORING_CQE_F_MORE set
in the flags. If this flag isn't set, the application must re-arm this request
by submitting a new one.

Reference: [io_uring and networking in 2023](https://github.com/axboe/liburing/wiki/io_uring-and-networking-in-2023#multi-shot)
2023-11-06 00:12:39 +02:00
Igor Anić 87a14f2b03 stdlib: remove flaky test
fixes ziglang#13660
2022-11-27 01:46:06 -05:00
Igor Anić 9947b47d80 stdlib: Thread.Condition wake only if signaled
Previous implementation didn't check whether there are pending signals
after return from futex.wait. While it is ok for broadcast case it can
result in multiple wakeups when only one thread is signaled.
This implementation checks that there are pending signals before
returning from wait.
It is similar to the original implementation but the without initial
signal check, here we first go to the futex and then check for pending
signal.
2022-11-21 17:26:54 +01:00
Igor Anić f229b74099 stdlib: fix condition variable broadcast FutexImpl
fixes #12877

Current implementation (before this fix) observes number of waiters when
broadcast occurs and then makes that number of wakeups.

If we have multiple threads waiting for wakeup which immediately go into
wait if wakeup is not for that thread (as described in the issue). The
same thread can get multiple wakeups while some got none.
That is not consistent with documented behavior for condition variable
broadcast: `Unblocks all threads currently blocked in a call to wait()
or timedWait() with a given Mutex.`.

This fix ensures that the thread waiting on futext is woken up on futex wake.
2022-11-17 20:58:45 +01:00
Igor Anić 9f6f460124 Sema: improve source location in errors
resolves #12793
2022-09-29 14:45:08 +03:00