xref: /illumos-gate/usr/src/lib/libsendfile/common/sendfile.c (revision 86d949f9497332fe19be6b5d711d265eb957439f)
1 
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License (the "License").
7  * You may not use this file except in compliance with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * sendfilev is the native interface : 32 bit app on 32 bit kernel
29  * and 64 bit app on 64 bit kernel. sendfilev64() is used by
30  * 32 bit apps on a 64 bit kernel or 32 bit kernel for large
31  * file offsets. Similar things apply to sendfile.
32  */
33 
34 #pragma weak sendfilev = _sendfilev
35 #pragma weak sendfile = _sendfile
36 
37 #include <sys/types.h>
38 #include <sys/syscall.h>
39 #include <sys/sendfile.h>
40 #include <errno.h>
41 
42 ssize_t
43 _sendfilev(int sock, const struct sendfilevec *vec, int sfvcnt, size_t *xferred)
44 {
45 	sysret_t rval;
46 	int error;
47 
48 	error = __systemcall(&rval, SYS_sendfilev, SENDFILEV, sock, vec,
49 	    sfvcnt, xferred);
50 	if (error != 0) {
51 		if (error == EINTR && *xferred != 0) {
52 			rval.sys_rval1 = *xferred;
53 		} else {
54 			(void) __set_errno(error);
55 		}
56 	}
57 	return ((ssize_t)rval.sys_rval1);
58 }
59 
60 ssize_t
61 _sendfile(int sock, int fd, off_t *off, size_t len)
62 {
63 	sysret_t rval;
64 	int error;
65 	struct sendfilevec sfv;
66 	size_t xferred;
67 
68 	sfv.sfv_fd = fd;
69 	sfv.sfv_flag = 0;
70 	sfv.sfv_off = *off;
71 	sfv.sfv_len = len;
72 	error = __systemcall(&rval, SYS_sendfilev, SENDFILEV, sock, &sfv,
73 	    1, &xferred);
74 	*off += xferred;
75 	if (error != 0) {
76 		if (error == EINTR && xferred != 0) {
77 			rval.sys_rval1 = xferred;
78 		} else {
79 			(void) __set_errno(error);
80 		}
81 	}
82 	return ((ssize_t)rval.sys_rval1);
83 }
84 
85 #if (!defined(_LP64))
86 
87 #pragma weak sendfilev64 = _sendfilev64
88 #pragma weak sendfile64 = _sendfile64
89 
90 ssize_t
91 _sendfilev64(int sock, const struct sendfilevec64 *vec, int sfvcnt,
92     size_t *xferred)
93 {
94 	sysret_t rval;
95 	int error;
96 
97 	error = __systemcall(&rval, SYS_sendfilev, SENDFILEV64, sock, vec,
98 	    sfvcnt, xferred);
99 	if (error != 0) {
100 		if (error == EINTR && *xferred != 0) {
101 			rval.sys_rval1 = *xferred;
102 		} else {
103 			(void) __set_errno(error);
104 		}
105 	}
106 	return ((ssize_t)rval.sys_rval1);
107 }
108 
109 ssize_t
110 _sendfile64(int sock, int fd, off64_t *off, size_t len)
111 {
112 	sysret_t rval;
113 	int error;
114 	struct sendfilevec64 sfv;
115 	size_t xferred;
116 
117 	sfv.sfv_fd = fd;
118 	sfv.sfv_flag = 0;
119 	sfv.sfv_off = *off;
120 	sfv.sfv_len = len;
121 	error = __systemcall(&rval, SYS_sendfilev, SENDFILEV64, sock, &sfv,
122 	    1, &xferred);
123 	*off += xferred;
124 	if (error != 0) {
125 		if (error == EINTR && xferred != 0) {
126 			rval.sys_rval1 = xferred;
127 		} else {
128 			(void) __set_errno(error);
129 		}
130 	}
131 	return ((ssize_t)rval.sys_rval1);
132 }
133 #endif
134