#define _OPT_PROTOS
#include <stdio.h>
#include <UNIX/os9def.h>
#include <errno.h>
#include <sg_codes.h>
#include <string.h>
#include <stdlib.h>
#include <modes.h>
#include <SPF/spf.h>

int writev(unsigned int fd, struct iovec *v, unsigned int n)
{
	u_int32 i, rv, nbytes = 0;
	int32 ri;
	char *buffer;
	error_code rc = 0;

	if (n <= 0) {
		errno = EINVAL;
		return -1;
	}

	/* If we have only one part, write it directly */
	if (n == 1 && v[0].iov_len > 0)
	{
		nbytes = rv = v[0].iov_len;
		rc = _os_write(fd, v[0].iov_base, &rv);

	} else {
		/* Check parameters and find the total number of bytes to be written. */
		for (i = 0; i < n; i++) {
			if (v[i].iov_base == NULL	/* no base pointer */
			|| (ri = v[i].iov_len) < 0	/* negative size */
			|| (nbytes += ri) < 0) {	/* integer overflow */
				errno = EINVAL;
				return -1;
			}
		}

		if (nbytes) {
			if (nbytes > 2048)
			{
				/*
				 * Allocate a temporary buffer to hold the data.
				 * Don't use alloca because threads tend to have smaller stacks.
				 */
				if ((buffer = (char *)malloc(nbytes)) == NULL) {
					return -1;
				}
				/* Copy the data from memory specified by VECTOR to BUFFER */
				for (rv = 0, i = 0; i < n; i++) {
		       		memcpy(buffer + rv, v[i].iov_base, v[i].iov_len);
					rv += v[i].iov_len;
		    	}
				rv = nbytes;
				rc = _os_write(fd, buffer, &rv);
				free(buffer);
			} else {
				char stack_buffer[2048];
				/* Copy the data from memory specified by VECTOR to BUFFER */
				for (rv = 0, i = 0; i < n; i++) {
		       		memcpy(stack_buffer + rv, v[i].iov_base, v[i].iov_len);
					rv += v[i].iov_len;
		    	}
				rv = nbytes;
				rc = _os_write(fd, stack_buffer, &rv);
			}
		}
	}
	errno = rc;
	return rv;
}

