(t *kernel.Task, file *vfs.FileDescription, src usermem.IOSequence, opts vfs.WriteOptions)
| 330 | } |
| 331 | |
| 332 | func write(t *kernel.Task, file *vfs.FileDescription, src usermem.IOSequence, opts vfs.WriteOptions) (int64, error) { |
| 333 | n, err := file.Write(t, src, opts) |
| 334 | if !linuxerr.Equals(linuxerr.ErrWouldBlock, err) { |
| 335 | return n, err |
| 336 | } |
| 337 | |
| 338 | allowBlock, deadline, hasDeadline := blockPolicy(t, file) |
| 339 | if !allowBlock { |
| 340 | return n, err |
| 341 | } |
| 342 | |
| 343 | // Register for notifications. |
| 344 | w, ch := waiter.NewChannelEntry(eventMaskWrite) |
| 345 | if err := file.EventRegister(&w); err != nil { |
| 346 | return n, err |
| 347 | } |
| 348 | |
| 349 | total := n |
| 350 | for { |
| 351 | // Shorten src to reflect bytes previously written. |
| 352 | src = src.DropFirst(int(n)) |
| 353 | |
| 354 | // Issue the request and break out if it completes with anything other than |
| 355 | // "would block". |
| 356 | n, err = file.Write(t, src, opts) |
| 357 | total += n |
| 358 | if !linuxerr.Equals(linuxerr.ErrWouldBlock, err) { |
| 359 | break |
| 360 | } |
| 361 | |
| 362 | // Wait for a notification that we should retry. |
| 363 | if err = t.BlockWithDeadline(ch, hasDeadline, deadline); err != nil { |
| 364 | if linuxerr.Equals(linuxerr.ETIMEDOUT, err) { |
| 365 | err = linuxerr.ErrWouldBlock |
| 366 | } |
| 367 | break |
| 368 | } |
| 369 | } |
| 370 | file.EventUnregister(&w) |
| 371 | return total, err |
| 372 | } |
| 373 | |
| 374 | // Pwrite64 implements Linux syscall pwrite64(2). |
| 375 | func Pwrite64(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { |
no test coverage detected
searching dependent graphs…