@@ -3111,6 +3111,67 @@ pub fn send(
3111
3111
return sendto (sockfd , buf , flags , null , 0 );
3112
3112
}
3113
3113
3114
+ pub const SendFileError = error {
3115
+ /// There was an unspecified error while reading from infd.
3116
+ InputOutput ,
3117
+
3118
+ /// There was insufficient memory for reading from infd.
3119
+ NoMem ,
3120
+
3121
+ /// The value provided for count overflows the maximum size of either
3122
+ /// infd or outfd.
3123
+ Overflow ,
3124
+
3125
+ /// Offset was provided, but infd is not seekable.
3126
+ Unseekable ,
3127
+
3128
+ /// The outfd is marked nonblocking and the requested operation would block, and
3129
+ /// there is no global event loop configured.
3130
+ WouldBlock ,
3131
+ } || UnexpectedError ;
3132
+
3133
+ /// Transfer data between file descriptors.
3134
+ ///
3135
+ /// The `sendfile` call copies `count` bytes from one file descriptor to another within the kernel. This can
3136
+ /// be more performant than transferring data from the kernel to user space and back, such as with
3137
+ /// `read` and `write` calls.
3138
+ ///
3139
+ /// The `infd` should be a file descriptor opened for reading, and `outfd` should be a file descriptor
3140
+ /// opened for writing. Copying will begin at `offset`, if not null, which will be updated to reflect
3141
+ /// the number of bytes read. If `offset` is null, the copying will begin at the current seek position,
3142
+ /// and the file position will be updated.
3143
+ pub fn sendfile (outfd : fd_t , infd : fd_t , offset : ? * u64 , count : usize ) SendFileError ! usize {
3144
+ while (true ) {
3145
+ var rc : usize = undefined ;
3146
+ var err : usize = undefined ;
3147
+ if (builtin .os == .linux ) {
3148
+ rc = system .sendfile (outfd , infd , offset , count );
3149
+ err = errno (rc );
3150
+ } else {
3151
+ @compileError ("sendfile unimplemented for this target" );
3152
+ }
3153
+
3154
+ switch (err ) {
3155
+ 0 = > return @intCast (usize , rc ),
3156
+ else = > return unexpectedErrno (err ),
3157
+
3158
+ EBADF = > unreachable ,
3159
+ EINVAL = > unreachable ,
3160
+ EFAULT = > unreachable ,
3161
+ EAGAIN = > if (std .event .Loop .instance ) | loop | {
3162
+ loop .waitUntilFdWritable (outfd );
3163
+ continue ;
3164
+ } else {
3165
+ return error .WouldBlock ;
3166
+ },
3167
+ EIO = > return error .InputOutput ,
3168
+ ENOMEM = > return error .NoMem ,
3169
+ EOVERFLOW = > return error .Overflow ,
3170
+ ESPIPE = > return error .Unseekable ,
3171
+ }
3172
+ }
3173
+ }
3174
+
3114
3175
pub const PollError = error {
3115
3176
/// The kernel had no space to allocate file descriptor tables.
3116
3177
SystemResources ,
0 commit comments