View | Details | Raw Unified | Return to bug 17366
Collapse All | Expand All

(-)Makefile (-1 / +1 lines)
Lines 31-37 Link Here
31
	flock.o fpathconf.o fstat.o fstatfs.o fsync.o getdirentries.o \
31
	flock.o fpathconf.o fstat.o fstatfs.o fsync.o getdirentries.o \
32
	getlogin.o getpeername.o getsockname.o getsockopt.o ioctl.o listen.o \
32
	getlogin.o getpeername.o getsockname.o getsockopt.o ioctl.o listen.o \
33
	msync.o nanosleep.o nfssvc.o open.o poll.o read.o readv.o recvfrom.o \
33
	msync.o nanosleep.o nfssvc.o open.o poll.o read.o readv.o recvfrom.o \
34
	recvmsg.o sched_yield.o select.o sendmsg.o sendto.o \
34
	recvmsg.o sched_yield.o select.o sendfile.o sendmsg.o sendto.o \
35
	setsockopt.o shutdown.o sigaction.o sigaltstack.o \
35
	setsockopt.o shutdown.o sigaction.o sigaltstack.o \
36
	signanosleep.o sigpending.o sigprocmask.o sigreturn.o sigsetmask.o \
36
	signanosleep.o sigpending.o sigprocmask.o sigreturn.o sigsetmask.o \
37
	sigsuspend.o socket.o \
37
	sigsuspend.o socket.o \
(-)uthread/Makefile.inc (+1 lines)
Lines 92-97 Link Here
92
	uthread_select.c \
92
	uthread_select.c \
93
	uthread_self.c \
93
	uthread_self.c \
94
	uthread_sem.c \
94
	uthread_sem.c \
95
	uthread_sendfile.c \
95
	uthread_sendmsg.c \
96
	uthread_sendmsg.c \
96
	uthread_sendto.c \
97
	uthread_sendto.c \
97
	uthread_seterrno.c \
98
	uthread_seterrno.c \
(-)uthread/uthread_sendfile.c (+149 lines)
Added Link Here
1
/*
2
 * Copyright (C) 2000 Jason Evans <jasone@canonware.com>.
3
 * All rights reserved.
4
 * 
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice(s), this list of conditions and the following disclaimer as
10
 *    the first lines of this file unmodified other than the possible
11
 *    addition of one or more copyright notices.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice(s), this list of conditions and the following disclaimer in
14
 *    the documentation and/or other materials provided with the
15
 *    distribution.
16
 * 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
18
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $FreeBSD$
30
 */
31
32
#include <sys/fcntl.h>
33
#include <sys/types.h>
34
#include <sys/socket.h>
35
#include <sys/uio.h>
36
#include <errno.h>
37
#ifdef _THREAD_SAFE
38
#include <pthread.h>
39
#include "pthread_private.h"
40
41
int
42
sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr,
43
    off_t *sbytes, int flags)
44
{
45
	int	ret, type, blocking;
46
	ssize_t wvret, num = 0;
47
	off_t	n, nwritten = 0;
48
49
	/* Write the headers if any. */
50
	if ((hdtr != NULL) && (hdtr->headers != NULL)) {
51
		if (wvret = writev(s, hdtr->headers, hdtr->hdr_cnt) == -1) {
52
			ret = -1;
53
			goto ERROR;
54
		} else
55
			nwritten += wvret;
56
	}
57
	
58
	/* Lock the descriptors. */
59
	if ((ret = _FD_LOCK(fd, FD_READ, NULL)) != 0) {
60
		goto ERROR;
61
	}
62
	if ((ret = _FD_LOCK(s, FD_WRITE, NULL)) != 0) {
63
		goto ERROR_1;
64
	}
65
	
66
	/* Check the descriptor access modes. */
67
	type = _thread_fd_table[fd]->flags & O_ACCMODE;
68
	if (type != O_RDONLY && type != O_RDWR) {
69
		/* File is not open for read. */
70
		errno = EBADF;
71
		goto ERROR_2;
72
	}
73
	type = _thread_fd_table[s]->flags & O_ACCMODE;
74
	if (type != O_WRONLY && type != O_RDWR) {
75
		/* File is not open for write. */
76
		errno = EBADF;
77
		goto ERROR_2;
78
	}
79
80
	/* Check if file operations are to block */
81
	blocking = ((_thread_fd_table[s]->flags & O_NONBLOCK) == 0);
82
	
83
	/*
84
	 * Loop while no error occurs and until the expected number of bytes are
85
	 * written.
86
	 */
87
	for (;;) {
88
		/* Perform a non-blocking sendfile syscall. */
89
		ret = _thread_sys_sendfile(fd, s, offset + num, nbytes - num,
90
		    NULL, &n, flags);
91
92
		if (ret == 0) {
93
			/* Writing completed. */
94
			num += n;
95
			break;
96
		} else if ((blocking) && (ret == -1) && (errno == EAGAIN)) {
97
			/*
98
			 * Some bytes were written but there are still more to
99
			 * write.
100
			 */
101
			
102
			/* Update the count of bytes written. */
103
			num += n;
104
105
			_thread_run->data.fd.fd = fd;
106
			_thread_kern_set_timeout(NULL);
107
108
			/* Reset the interrupted operation flag: */
109
			_thread_run->interrupted = 0;
110
111
			_thread_kern_sched_state(PS_FDW_WAIT, __FILE__,
112
			    __LINE__);
113
114
			if (_thread_run->interrupted) {
115
				/* Interrupted by a signal.  Return an error. */
116
				ret = -1;
117
				break;
118
			}
119
		} else {
120
			/* Error. */
121
			break;
122
		}
123
	}
124
125
  ERROR_2:
126
	_FD_UNLOCK(s, FD_WRITE);
127
  ERROR_1:
128
	_FD_UNLOCK(fd, FD_READ);
129
  ERROR:
130
	if (ret == 0) {
131
		/* Write the trailers, if any. */
132
		if ((hdtr != NULL) && (hdtr->trailers != NULL)) {
133
			if (wvret = writev(s, hdtr->trailers, hdtr->trl_cnt)
134
			    == -1)
135
				ret = -1;
136
			else
137
				nwritten += wvret;
138
		}
139
	}
140
	if (sbytes != NULL) {
141
		/*
142
		 * Number of bytes written in headers/trailers, plus in the main
143
		 * sendfile() loop.
144
		 */
145
		*sbytes = nwritten + num;
146
	}
147
	return ret;
148
}
149
#endif

Return to bug 17366