// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build unix

package poll

import (
	
	
	
)

// Writev wraps the writev system call.
func ( *FD) ( *[][]byte) (int64, error) {
	if  := .writeLock();  != nil {
		return 0, 
	}
	defer .writeUnlock()
	if  := .pd.prepareWrite(.isFile);  != nil {
		return 0, 
	}

	var  []syscall.Iovec
	if .iovecs != nil {
		 = *.iovecs
	}
	// TODO: read from sysconf(_SC_IOV_MAX)? The Linux default is
	// 1024 and this seems conservative enough for now. Darwin's
	// UIO_MAXIOV also seems to be 1024.
	 := 1024
	if runtime.GOOS == "aix" || runtime.GOOS == "solaris" {
		// IOV_MAX is set to XOPEN_IOV_MAX on AIX and Solaris.
		 = 16
	}

	var  int64
	var  error
	for len(*) > 0 {
		 = [:0]
		for ,  := range * {
			if len() == 0 {
				continue
			}
			 = append(, newIovecWithBase(&[0]))
			if .IsStream && len() > 1<<30 {
				[len()-1].SetLen(1 << 30)
				break // continue chunk on next writev
			}
			[len()-1].SetLen(len())
			if len() ==  {
				break
			}
		}
		if len() == 0 {
			break
		}
		if .iovecs == nil {
			.iovecs = new([]syscall.Iovec)
		}
		*.iovecs =  // cache

		var  uintptr
		,  = writev(.Sysfd, )
		if  == ^uintptr(0) {
			 = 0
		}
		TestHookDidWritev(int())
		 += int64()
		consume(, int64())
		for  := range  {
			[] = syscall.Iovec{}
		}
		if  != nil {
			if  == syscall.EINTR {
				continue
			}
			if  == syscall.EAGAIN {
				if  = .pd.waitWrite(.isFile);  == nil {
					continue
				}
			}
			break
		}
		if  == 0 {
			 = io.ErrUnexpectedEOF
			break
		}
	}
	return , 
}