authorgravatar for samuel.fiedler@proton.meSamuel Fiedler <samuel.fiedler@proton.me> 2026-01-05 11:57:25+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-06 14:25:44+02:00
log5ec8e45f3d11265634c4943daf95f85745d17c2f
treebbde64a89e61bd92ad79fbf0d040ab2457fffda8
parentfd2718f82ab70d99186f43845e4291515efb66a5

Io: add failing io (Io.failing)


1 files changed, 961 insertions(+), 0 deletions(-)

lib/std/Io.zig+961
......@@ -2491,3 +2491,964 @@ test {
24912491 _ = Semaphore;
24922492 _ = @import("Io/test.zig");
24932493}
2494
2495/// An implementation of `Io` which simulates a system supporting no `Io` operations.
2496///
2497/// This system has the following properties:
2498/// * Concurrency is unavailable.
2499/// * The stdio handles are pipes whose remote ends are already closed.
2500/// * The filesystem is entirely empty, including that the cwd is no longer present.
2501/// * The filesystem is full, so attempting to create entries always returns `error.NoSpaceLeft`.
2502/// * No entropy source is supported, so `randomSecure` always returns `error.EntropyUnavailable`, and `random` always returns (fills the buffer) with 0.
2503/// * No clocks are supported, so `now` and `sleep` always return `error.UnsupportedClock`.
2504/// * No network is connected, so network operations always return `error.NetworkDown`.
2505pub const failing: std.Io = .{
2506 .userdata = null,
2507 .vtable = &.{
2508 .crashHandler = noCrashHandler,
2509
2510 .async = noAsync,
2511 .concurrent = failingConcurrent,
2512 .await = unreachableAwait,
2513 .cancel = unreachableCancel,
2514
2515 .groupAsync = noGroupAsync,
2516 .groupConcurrent = failingGroupConcurrent,
2517 .groupAwait = unreachableGroupAwait,
2518 .groupCancel = unreachableGroupCancel,
2519
2520 .recancel = unreachableRecancel,
2521 .swapCancelProtection = unreachableSwapCancelProtection,
2522 .checkCancel = unreachableCheckCancel,
2523
2524 .futexWait = noFutexWait,
2525 .futexWaitUncancelable = noFutexWaitUncancelable,
2526 .futexWake = noFutexWake,
2527
2528 .operate = failingOperate,
2529 .batchAwaitAsync = unreachableBatchAwaitAsync,
2530 .batchAwaitConcurrent = unreachableBatchAwaitConcurrent,
2531 .batchCancel = unreachableBatchCancel,
2532
2533 .dirCreateDir = failingDirCreateDir,
2534 .dirCreateDirPath = failingDirCreateDirPath,
2535 .dirCreateDirPathOpen = failingDirCreateDirPathOpen,
2536 .dirOpenDir = failingDirOpenDir,
2537 .dirStat = failingDirStat,
2538 .dirStatFile = failingDirStatFile,
2539 .dirAccess = failingDirAccess,
2540 .dirCreateFile = failingDirCreateFile,
2541 .dirCreateFileAtomic = failingDirCreateFileAtomic,
2542 .dirOpenFile = failingDirOpenFile,
2543 .dirClose = unreachableDirClose,
2544 .dirRead = noDirRead,
2545 .dirRealPath = failingDirRealPath,
2546 .dirRealPathFile = failingDirRealPathFile,
2547 .dirDeleteFile = failingDirDeleteFile,
2548 .dirDeleteDir = failingDirDeleteDir,
2549 .dirRename = failingDirRename,
2550 .dirRenamePreserve = failingDirRenamePreserve,
2551 .dirSymLink = failingDirSymLink,
2552 .dirReadLink = failingDirReadLink,
2553 .dirSetOwner = failingDirSetOwner,
2554 .dirSetFileOwner = failingDirSetFileOwner,
2555 .dirSetPermissions = failingDirSetPermissions,
2556 .dirSetFilePermissions = failingDirSetFilePermissions,
2557 .dirSetTimestamps = noDirSetTimestamps,
2558 .dirHardLink = failingDirHardLink,
2559
2560 .fileStat = failingFileStat,
2561 .fileLength = failingFileLength,
2562 .fileClose = unreachableFileClose,
2563 .fileWritePositional = failingFileWritePositional,
2564 .fileWriteFileStreaming = noFileWriteFileStreaming,
2565 .fileWriteFilePositional = noFileWriteFilePositional,
2566 .fileReadPositional = failingFileReadPositional,
2567 .fileSeekBy = failingFileSeekBy,
2568 .fileSeekTo = failingFileSeekTo,
2569 .fileSync = failingFileSync,
2570 .fileIsTty = unreachableFileIsTty,
2571 .fileEnableAnsiEscapeCodes = unreachableFileEnableAnsiEscapeCodes,
2572 .fileSupportsAnsiEscapeCodes = unreachableFileSupportsAnsiEscapeCodes,
2573 .fileSetLength = failingFileSetLength,
2574 .fileSetOwner = failingFileSetOwner,
2575 .fileSetPermissions = failingFileSetPermissions,
2576 .fileSetTimestamps = noFileSetTimestamps,
2577 .fileLock = failingFileLock,
2578 .fileTryLock = failingFileTryLock,
2579 .fileUnlock = unreachableFileUnlock,
2580 .fileDowngradeLock = failingFileDowngradeLock,
2581 .fileRealPath = failingFileRealPath,
2582 .fileHardLink = failingFileHardLink,
2583
2584 .fileMemoryMapCreate = failingFileMemoryMapCreate,
2585 .fileMemoryMapDestroy = unreachableFileMemoryMapDestroy,
2586 .fileMemoryMapSetLength = unreachableFileMemoryMapSetLength,
2587 .fileMemoryMapRead = unreachableFileMemoryMapRead,
2588 .fileMemoryMapWrite = unreachableFileMemoryMapWrite,
2589
2590 .processExecutableOpen = failingProcessExecutableOpen,
2591 .processExecutablePath = failingProcessExecutablePath,
2592 .lockStderr = unreachableLockStderr,
2593 .tryLockStderr = noTryLockStderr,
2594 .unlockStderr = unreachableUnlockStderr,
2595 .processCurrentPath = failingProcessCurrentPath,
2596 .processSetCurrentDir = failingProcessSetCurrentDir,
2597 .processSetCurrentPath = failingProcessSetCurrentPath,
2598 .processReplace = failingProcessReplace,
2599 .processReplacePath = failingProcessReplacePath,
2600 .processSpawn = failingProcessSpawn,
2601 .processSpawnPath = failingProcessSpawnPath,
2602 .childWait = unreachableChildWait,
2603 .childKill = unreachableChildKill,
2604
2605 .progressParentFile = failingProgressParentFile,
2606
2607 .random = noRandom,
2608 .randomSecure = failingRandomSecure,
2609
2610 .now = noNow,
2611 .clockResolution = failingClockResolution,
2612 .sleep = noSleep,
2613
2614 .netListenIp = failingNetListenIp,
2615 .netAccept = failingNetAccept,
2616 .netBindIp = failingNetBindIp,
2617 .netConnectIp = failingNetConnectIp,
2618 .netListenUnix = failingNetListenUnix,
2619 .netConnectUnix = failingNetConnectUnix,
2620 .netSocketCreatePair = failingNetSocketCreatePair,
2621 .netSend = failingNetSend,
2622 .netRead = failingNetRead,
2623 .netWrite = failingNetWrite,
2624 .netWriteFile = failingNetWriteFile,
2625 .netClose = unreachableNetClose,
2626 .netShutdown = failingNetShutdown,
2627 .netInterfaceNameResolve = failingNetInterfaceNameResolve,
2628 .netInterfaceName = unreachableNetInterfaceName,
2629 .netLookup = failingNetLookup,
2630 },
2631};
2632
2633pub fn noCrashHandler(userdata: ?*anyopaque) void {
2634 _ = userdata;
2635}
2636
2637pub fn noAsync(userdata: ?*anyopaque, result: []u8, result_alignment: std.mem.Alignment, context: []const u8, context_alignment: std.mem.Alignment, start: *const fn (context: *const anyopaque, result: *anyopaque) void) ?*AnyFuture {
2638 _ = userdata;
2639 _ = result_alignment;
2640 _ = context_alignment;
2641 start(context.ptr, result.ptr);
2642 return null;
2643}
2644
2645pub fn failingConcurrent(
2646 userdata: ?*anyopaque,
2647 result_len: usize,
2648 result_alignment: std.mem.Alignment,
2649 context: []const u8,
2650 context_alignment: std.mem.Alignment,
2651 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
2652) ConcurrentError!*AnyFuture {
2653 _ = userdata;
2654 _ = result_len;
2655 _ = result_alignment;
2656 _ = context;
2657 _ = context_alignment;
2658 _ = start;
2659 return error.ConcurrencyUnavailable;
2660}
2661
2662pub fn unreachableAwait(
2663 userdata: ?*anyopaque,
2664 any_future: *AnyFuture,
2665 result: []u8,
2666 result_alignment: std.mem.Alignment,
2667) void {
2668 _ = userdata;
2669 _ = any_future;
2670 _ = result;
2671 _ = result_alignment;
2672 unreachable;
2673}
2674
2675pub fn unreachableCancel(
2676 userdata: ?*anyopaque,
2677 any_future: *AnyFuture,
2678 result: []u8,
2679 result_alignment: std.mem.Alignment,
2680) void {
2681 _ = userdata;
2682 _ = any_future;
2683 _ = result;
2684 _ = result_alignment;
2685 unreachable;
2686}
2687
2688pub fn noGroupAsync(
2689 userdata: ?*anyopaque,
2690 group: *Group,
2691 context: []const u8,
2692 context_alignment: std.mem.Alignment,
2693 start: *const fn (context: *const anyopaque) void,
2694) void {
2695 _ = userdata;
2696 _ = group;
2697 _ = context_alignment;
2698 start(context.ptr);
2699}
2700
2701pub fn failingGroupConcurrent(
2702 userdata: ?*anyopaque,
2703 group: *Group,
2704 context: []const u8,
2705 context_alignment: std.mem.Alignment,
2706 start: *const fn (context: *const anyopaque) void,
2707) ConcurrentError!void {
2708 _ = userdata;
2709 _ = group;
2710 _ = context;
2711 _ = context_alignment;
2712 _ = start;
2713 return error.ConcurrencyUnavailable;
2714}
2715
2716pub fn unreachableGroupAwait(userdata: ?*anyopaque, group: *Group, token: *anyopaque) Cancelable!void {
2717 _ = userdata;
2718 _ = group;
2719 _ = token;
2720 unreachable;
2721}
2722
2723pub fn unreachableGroupCancel(userdata: ?*anyopaque, group: *Group, token: *anyopaque) void {
2724 _ = userdata;
2725 _ = group;
2726 _ = token;
2727 unreachable;
2728}
2729
2730pub fn unreachableRecancel(userdata: ?*anyopaque) void {
2731 _ = userdata;
2732 unreachable;
2733}
2734
2735pub fn unreachableSwapCancelProtection(userdata: ?*anyopaque, new: CancelProtection) CancelProtection {
2736 _ = userdata;
2737 _ = new;
2738 unreachable;
2739}
2740
2741pub fn unreachableCheckCancel(userdata: ?*anyopaque) Cancelable!void {
2742 _ = userdata;
2743 unreachable;
2744}
2745
2746pub fn noFutexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Timeout) Cancelable!void {
2747 _ = userdata;
2748 std.debug.assert(ptr.* == expected or timeout != .none);
2749}
2750
2751pub fn noFutexWaitUncancelable(userdata: ?*anyopaque, ptr: *const u32, expected: u32) void {
2752 _ = userdata;
2753 std.debug.assert(ptr.* == expected);
2754}
2755
2756pub fn noFutexWake(userdata: ?*anyopaque, ptr: *const u32, max_waiters: u32) void {
2757 _ = userdata;
2758 _ = ptr;
2759 _ = max_waiters;
2760 // no-op
2761}
2762
2763pub fn failingOperate(userdata: ?*anyopaque, operation: Operation) Cancelable!Operation.Result {
2764 _ = userdata;
2765 return switch (operation) {
2766 .file_read_streaming => .{ .file_read_streaming = error.InputOutput },
2767 .file_write_streaming => .{ .file_write_streaming = error.InputOutput },
2768 .device_io_control => unreachable,
2769 .net_receive => .{ .net_receive = .{ error.NetworkDown, 0 } },
2770 };
2771}
2772
2773pub fn unreachableBatchAwaitAsync(userdata: ?*anyopaque, b: *Batch) Cancelable!void {
2774 _ = userdata;
2775 _ = b;
2776 unreachable;
2777}
2778
2779pub fn unreachableBatchAwaitConcurrent(userdata: ?*anyopaque, b: *Batch, timeout: Timeout) Batch.AwaitConcurrentError!void {
2780 _ = userdata;
2781 _ = b;
2782 _ = timeout;
2783 unreachable;
2784}
2785
2786pub fn unreachableBatchCancel(userdata: ?*anyopaque, b: *Batch) void {
2787 _ = userdata;
2788 _ = b;
2789 unreachable;
2790}
2791
2792pub fn failingDirCreateDir(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {
2793 _ = userdata;
2794 _ = dir;
2795 _ = sub_path;
2796 _ = permissions;
2797 return error.NoSpaceLeft;
2798}
2799
2800pub fn failingDirCreateDirPath(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirPathError!Dir.CreatePathStatus {
2801 _ = userdata;
2802 _ = dir;
2803 _ = sub_path;
2804 _ = permissions;
2805 return error.NoSpaceLeft;
2806}
2807
2808pub fn failingDirCreateDirPathOpen(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions, options: Dir.OpenOptions) Dir.CreateDirPathOpenError!Dir {
2809 _ = userdata;
2810 _ = dir;
2811 _ = sub_path;
2812 _ = permissions;
2813 _ = options;
2814 return error.NoSpaceLeft;
2815}
2816
2817pub fn failingDirOpenDir(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.OpenOptions) Dir.OpenError!Dir {
2818 _ = userdata;
2819 _ = dir;
2820 _ = sub_path;
2821 _ = options;
2822 return error.FileNotFound;
2823}
2824
2825pub fn failingDirStat(userdata: ?*anyopaque, dir: Dir) Dir.StatError!Dir.Stat {
2826 _ = userdata;
2827 _ = dir;
2828 return error.Streaming;
2829}
2830
2831pub fn failingDirStatFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.StatFileOptions) Dir.StatFileError!File.Stat {
2832 _ = userdata;
2833 _ = dir;
2834 _ = sub_path;
2835 _ = options;
2836 return error.FileNotFound;
2837}
2838
2839pub fn failingDirAccess(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.AccessOptions) Dir.AccessError!void {
2840 _ = userdata;
2841 _ = dir;
2842 _ = sub_path;
2843 _ = options;
2844 return error.FileNotFound;
2845}
2846
2847pub fn failingDirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: File.CreateFlags) File.OpenError!File {
2848 _ = userdata;
2849 _ = dir;
2850 _ = sub_path;
2851 _ = options;
2852 return error.NoSpaceLeft;
2853}
2854
2855pub fn failingDirCreateFileAtomic(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.CreateFileAtomicOptions) Dir.CreateFileAtomicError!File.Atomic {
2856 _ = userdata;
2857 _ = dir;
2858 _ = sub_path;
2859 _ = options;
2860 return error.NoSpaceLeft;
2861}
2862
2863pub fn failingDirOpenFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
2864 _ = userdata;
2865 _ = dir;
2866 _ = sub_path;
2867 _ = flags;
2868 return error.FileNotFound;
2869}
2870
2871pub fn unreachableDirClose(userdata: ?*anyopaque, dirs: []const Dir) void {
2872 _ = userdata;
2873 _ = dirs;
2874 unreachable;
2875}
2876
2877pub fn noDirRead(userdata: ?*anyopaque, dir_reader: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
2878 _ = userdata;
2879 _ = dir_reader;
2880 _ = buffer;
2881 return 0;
2882}
2883
2884pub fn failingDirRealPath(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize {
2885 _ = userdata;
2886 _ = dir;
2887 _ = out_buffer;
2888 return error.FileNotFound;
2889}
2890
2891pub fn failingDirRealPathFile(userdata: ?*anyopaque, dir: Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize {
2892 _ = userdata;
2893 _ = dir;
2894 _ = path_name;
2895 _ = out_buffer;
2896 return error.FileNotFound;
2897}
2898
2899pub fn failingDirDeleteFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteFileError!void {
2900 _ = userdata;
2901 _ = dir;
2902 _ = sub_path;
2903 return error.FileNotFound;
2904}
2905
2906pub fn failingDirDeleteDir(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteDirError!void {
2907 _ = userdata;
2908 _ = dir;
2909 _ = sub_path;
2910 return error.FileNotFound;
2911}
2912
2913pub fn failingDirRename(userdata: ?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenameError!void {
2914 _ = userdata;
2915 _ = old_dir;
2916 _ = old_sub_path;
2917 _ = new_dir;
2918 _ = new_sub_path;
2919 return error.FileNotFound;
2920}
2921
2922pub fn failingDirRenamePreserve(userdata: ?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenamePreserveError!void {
2923 _ = userdata;
2924 _ = old_dir;
2925 _ = old_sub_path;
2926 _ = new_dir;
2927 _ = new_sub_path;
2928 return error.FileNotFound;
2929}
2930
2931pub fn failingDirSymLink(userdata: ?*anyopaque, dir: Dir, target_path: []const u8, sym_link_path: []const u8, flags: Dir.SymLinkFlags) Dir.SymLinkError!void {
2932 _ = userdata;
2933 _ = dir;
2934 _ = target_path;
2935 _ = sym_link_path;
2936 _ = flags;
2937 return error.FileNotFound;
2938}
2939
2940pub fn failingDirReadLink(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {
2941 _ = userdata;
2942 _ = dir;
2943 _ = sub_path;
2944 _ = buffer;
2945 return error.FileNotFound;
2946}
2947
2948pub fn failingDirSetOwner(userdata: ?*anyopaque, dir: Dir, owner: ?File.Uid, group: ?File.Gid) Dir.SetOwnerError!void {
2949 _ = userdata;
2950 _ = dir;
2951 _ = owner;
2952 _ = group;
2953 return error.FileNotFound;
2954}
2955
2956pub fn failingDirSetFileOwner(userdata: ?*anyopaque, dir: std.Io.Dir, sub_path: []const u8, owner: ?File.Uid, group: ?File.Gid, options: Dir.SetFileOwnerOptions) Dir.SetFileOwnerError!void {
2957 _ = userdata;
2958 _ = dir;
2959 _ = sub_path;
2960 _ = owner;
2961 _ = group;
2962 _ = options;
2963 return error.FileNotFound;
2964}
2965
2966pub fn failingDirSetPermissions(userdata: ?*anyopaque, dir: Dir, permissions: Dir.Permissions) Dir.SetPermissionsError!void {
2967 _ = userdata;
2968 _ = dir;
2969 _ = permissions;
2970 return error.FileNotFound;
2971}
2972
2973pub fn failingDirSetFilePermissions(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: File.Permissions, options: Dir.SetFilePermissionsOptions) Dir.SetFilePermissionsError!void {
2974 _ = userdata;
2975 _ = dir;
2976 _ = sub_path;
2977 _ = permissions;
2978 _ = options;
2979 return error.FileNotFound;
2980}
2981
2982pub fn noDirSetTimestamps(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.SetTimestampsOptions) Dir.SetTimestampsError!void {
2983 _ = userdata;
2984 _ = dir;
2985 _ = sub_path;
2986 _ = options;
2987 // no-op
2988}
2989
2990pub fn failingDirHardLink(userdata: ?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8, options: Dir.HardLinkOptions) Dir.HardLinkError!void {
2991 _ = userdata;
2992 _ = old_dir;
2993 _ = old_sub_path;
2994 _ = new_dir;
2995 _ = new_sub_path;
2996 _ = options;
2997 return error.FileNotFound;
2998}
2999
3000pub fn failingFileStat(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
3001 _ = userdata;
3002 _ = file;
3003 return error.Streaming;
3004}
3005
3006pub fn failingFileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 {
3007 _ = userdata;
3008 _ = file;
3009 return error.Streaming;
3010}
3011
3012pub fn unreachableFileClose(userdata: ?*anyopaque, files: []const File) void {
3013 _ = userdata;
3014 _ = files;
3015 unreachable;
3016}
3017
3018pub fn failingFileWritePositional(userdata: ?*anyopaque, file: File, header: []const u8, data: []const []const u8, splat: usize, offset: u64) File.WritePositionalError!usize {
3019 _ = userdata;
3020 _ = file;
3021 _ = header;
3022 _ = offset;
3023 for (data[0 .. data.len - 1]) |item| {
3024 if (item.len > 0) return error.BrokenPipe;
3025 }
3026 if (data[data.len - 1].len != 0 and splat != 0) return error.BrokenPipe;
3027 return 0;
3028}
3029
3030pub fn noFileWriteFileStreaming(userdata: ?*anyopaque, file: File, header: []const u8, file_reader: *Io.File.Reader, limit: Io.Limit) File.Writer.WriteFileError!usize {
3031 _ = userdata;
3032 _ = file;
3033 _ = header;
3034 _ = file_reader;
3035 _ = limit;
3036 return error.Unimplemented;
3037}
3038
3039pub fn noFileWriteFilePositional(userdata: ?*anyopaque, file: File, header: []const u8, file_reader: *Io.File.Reader, limit: Io.Limit, offset: u64) File.WriteFilePositionalError!usize {
3040 _ = userdata;
3041 _ = file;
3042 _ = header;
3043 _ = file_reader;
3044 _ = limit;
3045 _ = offset;
3046 return error.Unimplemented;
3047}
3048
3049pub fn failingFileReadPositional(userdata: ?*anyopaque, file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {
3050 _ = userdata;
3051 _ = file;
3052 _ = offset;
3053 for (data) |item| {
3054 if (item.len > 0) return error.InputOutput;
3055 }
3056 return 0;
3057}
3058
3059pub fn failingFileSeekBy(userdata: ?*anyopaque, file: File, relative_offset: i64) File.SeekError!void {
3060 _ = userdata;
3061 _ = file;
3062 _ = relative_offset;
3063 return error.Unseekable;
3064}
3065
3066pub fn failingFileSeekTo(userdata: ?*anyopaque, file: File, absolute_offset: u64) File.SeekError!void {
3067 _ = userdata;
3068 _ = file;
3069 _ = absolute_offset;
3070 return error.Unseekable;
3071}
3072
3073pub fn failingFileSync(userdata: ?*anyopaque, file: File) File.SyncError!void {
3074 _ = userdata;
3075 _ = file;
3076 return error.NoSpaceLeft;
3077}
3078
3079pub fn unreachableFileIsTty(userdata: ?*anyopaque, file: File) Cancelable!bool {
3080 _ = userdata;
3081 _ = file;
3082 unreachable;
3083}
3084
3085pub fn unreachableFileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiEscapeCodesError!void {
3086 _ = userdata;
3087 _ = file;
3088 unreachable;
3089}
3090
3091pub fn unreachableFileSupportsAnsiEscapeCodes(userdata: ?*anyopaque, file: File) Cancelable!bool {
3092 _ = userdata;
3093 _ = file;
3094 unreachable;
3095}
3096
3097pub fn failingFileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthError!void {
3098 _ = userdata;
3099 _ = file;
3100 _ = length;
3101 return error.NonResizable;
3102}
3103
3104pub fn failingFileSetOwner(userdata: ?*anyopaque, file: File, owner: ?File.Uid, group: ?File.Gid) File.SetOwnerError!void {
3105 _ = userdata;
3106 _ = file;
3107 _ = owner;
3108 _ = group;
3109 return error.FileNotFound;
3110}
3111
3112pub fn failingFileSetPermissions(userdata: ?*anyopaque, file: File, permissions: File.Permissions) File.SetPermissionsError!void {
3113 _ = userdata;
3114 _ = file;
3115 _ = permissions;
3116 return error.FileNotFound;
3117}
3118
3119pub fn noFileSetTimestamps(userdata: ?*anyopaque, file: File, options: File.SetTimestampsOptions) File.SetTimestampsError!void {
3120 _ = userdata;
3121 _ = file;
3122 _ = options;
3123 // no-op
3124}
3125
3126pub fn failingFileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!void {
3127 _ = userdata;
3128 _ = file;
3129 _ = lock;
3130 return error.FileLocksUnsupported;
3131}
3132
3133pub fn failingFileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!bool {
3134 _ = userdata;
3135 _ = file;
3136 _ = lock;
3137 return error.FileLocksUnsupported;
3138}
3139
3140pub fn unreachableFileUnlock(userdata: ?*anyopaque, file: File) void {
3141 _ = userdata;
3142 _ = file;
3143 unreachable;
3144}
3145
3146pub fn failingFileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError!void {
3147 _ = userdata;
3148 _ = file;
3149 // no-op
3150}
3151
3152pub fn failingFileRealPath(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize {
3153 _ = userdata;
3154 _ = file;
3155 _ = out_buffer;
3156 return error.FileNotFound;
3157}
3158
3159pub fn failingFileHardLink(userdata: ?*anyopaque, file: File, new_dir: Dir, new_sub_path: []const u8, options: File.HardLinkOptions) File.HardLinkError!void {
3160 _ = userdata;
3161 _ = file;
3162 _ = new_dir;
3163 _ = new_sub_path;
3164 _ = options;
3165 return error.FileNotFound;
3166}
3167
3168pub fn failingFileMemoryMapCreate(userdata: ?*anyopaque, file: File, options: File.MemoryMap.CreateOptions) File.MemoryMap.CreateError!File.MemoryMap {
3169 _ = userdata;
3170 _ = file;
3171 _ = options;
3172 return error.AccessDenied;
3173}
3174
3175pub fn unreachableFileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void {
3176 _ = userdata;
3177 _ = mm;
3178 unreachable;
3179}
3180
3181pub fn unreachableFileMemoryMapSetLength(userdata: ?*anyopaque, mm: *File.MemoryMap, new_len: usize) File.MemoryMap.SetLengthError!void {
3182 _ = userdata;
3183 _ = mm;
3184 _ = new_len;
3185 unreachable;
3186}
3187
3188pub fn unreachableFileMemoryMapRead(userdata: ?*anyopaque, mm: *File.MemoryMap) File.ReadPositionalError!void {
3189 _ = userdata;
3190 _ = mm;
3191 unreachable;
3192}
3193
3194pub fn unreachableFileMemoryMapWrite(userdata: ?*anyopaque, mm: *File.MemoryMap) File.WritePositionalError!void {
3195 _ = userdata;
3196 _ = mm;
3197 unreachable;
3198}
3199
3200pub fn failingProcessExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) std.process.OpenExecutableError!File {
3201 _ = userdata;
3202 _ = flags;
3203 return error.FileNotFound;
3204}
3205
3206pub fn failingProcessExecutablePath(userdata: ?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize {
3207 _ = userdata;
3208 _ = buffer;
3209 return error.FileNotFound;
3210}
3211
3212pub fn unreachableLockStderr(userdata: ?*anyopaque, terminal_mode: ?Terminal.Mode) Cancelable!LockedStderr {
3213 _ = userdata;
3214 _ = terminal_mode;
3215 unreachable;
3216}
3217
3218pub fn noTryLockStderr(userdata: ?*anyopaque, terminal_mode: ?Terminal.Mode) Cancelable!?LockedStderr {
3219 _ = userdata;
3220 _ = terminal_mode;
3221 return null;
3222}
3223
3224pub fn unreachableUnlockStderr(userdata: ?*anyopaque) void {
3225 _ = userdata;
3226 unreachable;
3227}
3228
3229pub fn failingProcessCurrentPath(userdata: ?*anyopaque, buffer: []u8) std.process.CurrentPathError!usize {
3230 _ = userdata;
3231 _ = buffer;
3232 return error.CurrentDirUnlinked;
3233}
3234
3235pub fn failingProcessSetCurrentDir(userdata: ?*anyopaque, dir: Dir) std.process.SetCurrentDirError!void {
3236 _ = userdata;
3237 _ = dir;
3238 return error.FileNotFound;
3239}
3240
3241pub fn failingProcessSetCurrentPath(userdata: ?*anyopaque, path: []const u8) std.process.SetCurrentPathError!void {
3242 _ = userdata;
3243 _ = path;
3244 return error.FileNotFound;
3245}
3246
3247pub fn failingProcessReplace(userdata: ?*anyopaque, options: std.process.ReplaceOptions) std.process.ReplaceError {
3248 _ = userdata;
3249 _ = options;
3250 return error.OperationUnsupported;
3251}
3252
3253pub fn failingProcessReplacePath(userdata: ?*anyopaque, dir: Dir, options: std.process.ReplaceOptions) std.process.ReplaceError {
3254 _ = userdata;
3255 _ = dir;
3256 _ = options;
3257 return error.OperationUnsupported;
3258}
3259
3260pub fn failingProcessSpawn(userdata: ?*anyopaque, options: std.process.SpawnOptions) std.process.SpawnError!std.process.Child {
3261 _ = userdata;
3262 _ = options;
3263 return error.OperationUnsupported;
3264}
3265
3266pub fn failingProcessSpawnPath(userdata: ?*anyopaque, dir: Dir, options: std.process.SpawnOptions) std.process.SpawnError!std.process.Child {
3267 _ = userdata;
3268 _ = dir;
3269 _ = options;
3270 return error.OperationUnsupported;
3271}
3272
3273pub fn unreachableChildWait(userdata: ?*anyopaque, child: *std.process.Child) std.process.Child.WaitError!std.process.Child.Term {
3274 _ = userdata;
3275 _ = child;
3276 unreachable;
3277}
3278
3279pub fn unreachableChildKill(userdata: ?*anyopaque, child: *std.process.Child) void {
3280 _ = userdata;
3281 _ = child;
3282 unreachable;
3283}
3284
3285pub fn failingProgressParentFile(userdata: ?*anyopaque) std.Progress.ParentFileError!File {
3286 _ = userdata;
3287 return error.UnsupportedOperation;
3288}
3289
3290pub fn noRandom(userdata: ?*anyopaque, buffer: []u8) void {
3291 _ = userdata;
3292 @memset(buffer, 0);
3293}
3294
3295pub fn failingRandomSecure(userdata: ?*anyopaque, buffer: []u8) RandomSecureError!void {
3296 _ = userdata;
3297 _ = buffer;
3298 return error.EntropyUnavailable;
3299}
3300
3301pub fn noNow(userdata: ?*anyopaque, clock: Clock) Timestamp {
3302 _ = userdata;
3303 _ = clock;
3304 return .zero;
3305}
3306
3307pub fn failingClockResolution(userdata: ?*anyopaque, clock: Clock) Clock.ResolutionError!Duration {
3308 _ = userdata;
3309 _ = clock;
3310 return error.ClockUnavailable;
3311}
3312
3313pub fn noSleep(userdata: ?*anyopaque, clock: Timeout) Cancelable!void {
3314 _ = userdata;
3315 _ = clock;
3316}
3317
3318pub fn failingNetListenIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ListenOptions) net.IpAddress.ListenError!net.Socket {
3319 _ = userdata;
3320 _ = address;
3321 _ = options;
3322 return error.NetworkDown;
3323}
3324
3325pub fn failingNetAccept(userdata: ?*anyopaque, listen_fd: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket {
3326 _ = userdata;
3327 _ = listen_fd;
3328 _ = options;
3329 return error.NetworkDown;
3330}
3331
3332pub fn failingNetBindIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.BindOptions) net.IpAddress.BindError!net.Socket {
3333 _ = userdata;
3334 _ = address;
3335 _ = options;
3336 return error.NetworkDown;
3337}
3338
3339pub fn failingNetConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Socket {
3340 _ = userdata;
3341 _ = address;
3342 _ = options;
3343 return error.NetworkDown;
3344}
3345
3346pub fn failingNetListenUnix(userdata: ?*anyopaque, address: *const net.UnixAddress, options: net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle {
3347 _ = userdata;
3348 _ = address;
3349 _ = options;
3350 return error.NetworkDown;
3351}
3352
3353pub fn failingNetConnectUnix(userdata: ?*anyopaque, address: *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle {
3354 _ = userdata;
3355 _ = address;
3356 return error.NetworkDown;
3357}
3358
3359pub fn failingNetSocketCreatePair(userdata: ?*anyopaque, options: net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket {
3360 _ = userdata;
3361 _ = options;
3362 return error.OperationUnsupported;
3363}
3364
3365pub fn failingNetSend(userdata: ?*anyopaque, handle: net.Socket.Handle, messages: []net.OutgoingMessage, flags: net.SendFlags) struct { ?net.Socket.SendError, usize } {
3366 _ = userdata;
3367 _ = handle;
3368 _ = messages;
3369 _ = flags;
3370 return .{ error.NetworkDown, 0 };
3371}
3372
3373pub fn failingNetRead(userdata: ?*anyopaque, src: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
3374 _ = userdata;
3375 _ = src;
3376 _ = data;
3377 return error.NetworkDown;
3378}
3379
3380pub fn failingNetWrite(userdata: ?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize {
3381 _ = userdata;
3382 _ = dest;
3383 _ = header;
3384 _ = data;
3385 _ = splat;
3386 return error.NetworkDown;
3387}
3388
3389pub fn failingNetWriteFile(userdata: ?*anyopaque, handle: net.Socket.Handle, header: []const u8, file_reader: *Io.File.Reader, limit: Io.Limit) net.Stream.Writer.WriteFileError!usize {
3390 _ = userdata;
3391 _ = handle;
3392 _ = header;
3393 _ = file_reader;
3394 _ = limit;
3395 return error.NetworkDown;
3396}
3397
3398pub fn unreachableNetClose(userdata: ?*anyopaque, handle: []const net.Socket.Handle) void {
3399 _ = userdata;
3400 _ = handle;
3401 unreachable;
3402}
3403
3404pub fn failingNetShutdown(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {
3405 _ = userdata;
3406 _ = handle;
3407 _ = how;
3408 return error.NetworkDown;
3409}
3410
3411pub fn failingNetInterfaceNameResolve(userdata: ?*anyopaque, name: *const net.Interface.Name) net.Interface.Name.ResolveError!net.Interface {
3412 _ = userdata;
3413 _ = name;
3414 return error.InterfaceNotFound;
3415}
3416
3417pub fn unreachableNetInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
3418 _ = userdata;
3419 _ = interface;
3420 unreachable;
3421}
3422
3423pub fn failingNetLookup(userdata: ?*anyopaque, host_name: net.HostName, resolved: *Queue(net.HostName.LookupResult), options: net.HostName.LookupOptions) net.HostName.LookupError!void {
3424 _ = userdata;
3425 _ = host_name;
3426 _ = resolved;
3427 _ = options;
3428 return error.NetworkDown;
3429}
3430
3431test failing {
3432 const f: Io = .failing;
3433 // file stuff
3434 try std.testing.expectError(error.NoSpaceLeft, Dir.createDir(.cwd(), f, "test", .default_dir));
3435 try std.testing.expectError(error.NoSpaceLeft, Dir.createFile(.cwd(), f, "test", .{}));
3436 try std.testing.expectError(error.FileNotFound, Dir.openDir(.cwd(), f, "test", .{}));
3437 try std.testing.expectError(error.FileNotFound, Dir.openFile(.cwd(), f, "test", .{}));
3438 try File.writeStreamingAll(.stdout(), f, &.{});
3439 try std.testing.expectError(error.AccessDenied, File.MemoryMap.create(f, .stdout(), .{ .len = 0 }));
3440 // async stuff
3441 const closure = struct {
3442 var foo: usize = 0;
3443 fn doOp() void {
3444 foo = 4;
3445 }
3446 };
3447 var future = f.async(closure.doOp, .{});
3448 _ = future.await(f);
3449 try std.testing.expect(closure.foo == 4);
3450 // random stuff
3451 var buffer: [1]u8 = undefined;
3452 f.random(&buffer);
3453 try std.testing.expect(buffer[0] == 0);
3454}