Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105766390
D19917.id66790.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D19917.id66790.diff
View Options
Index: sys/amd64/linux32/linux32_dummy.c
===================================================================
--- sys/amd64/linux32/linux32_dummy.c
+++ sys/amd64/linux32/linux32_dummy.c
@@ -72,7 +72,6 @@
DUMMY(quotactl);
DUMMY(bdflush);
DUMMY(sysfs);
-DUMMY(sendfile);
DUMMY(setfsuid);
DUMMY(setfsgid);
DUMMY(pivot_root);
Index: sys/amd64/linux32/linux32_proto.h
===================================================================
--- sys/amd64/linux32/linux32_proto.h
+++ sys/amd64/linux32/linux32_proto.h
@@ -604,7 +604,10 @@
char uoss_l_[PADL_(l_stack_t *)]; l_stack_t * uoss; char uoss_r_[PADR_(l_stack_t *)];
};
struct linux_sendfile_args {
- register_t dummy;
+ char out_l_[PADL_(l_int)]; l_int out; char out_r_[PADR_(l_int)];
+ char in_l_[PADL_(l_int)]; l_int in; char in_r_[PADR_(l_int)];
+ char offset_l_[PADL_(l_long *)]; l_long * offset; char offset_r_[PADR_(l_long *)];
+ char count_l_[PADL_(l_size_t)]; l_size_t count; char count_r_[PADR_(l_size_t)];
};
struct linux_vfork_args {
register_t dummy;
@@ -733,6 +736,12 @@
char tid_l_[PADL_(int)]; int tid; char tid_r_[PADR_(int)];
char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
};
+struct linux_sendfile64_args {
+ char out_l_[PADL_(l_int)]; l_int out; char out_r_[PADR_(l_int)];
+ char in_l_[PADL_(l_int)]; l_int in; char in_r_[PADR_(l_int)];
+ char offset_l_[PADL_(l_loff_t *)]; l_loff_t * offset; char offset_r_[PADR_(l_loff_t *)];
+ char count_l_[PADL_(l_size_t)]; l_size_t count; char count_r_[PADR_(l_size_t)];
+};
struct linux_sys_futex_args {
char uaddr_l_[PADL_(void *)]; void * uaddr; char uaddr_r_[PADR_(void *)];
char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
@@ -1687,6 +1696,7 @@
int linux_lremovexattr(struct thread *, struct linux_lremovexattr_args *);
int linux_fremovexattr(struct thread *, struct linux_fremovexattr_args *);
int linux_tkill(struct thread *, struct linux_tkill_args *);
+int linux_sendfile64(struct thread *, struct linux_sendfile64_args *);
int linux_sys_futex(struct thread *, struct linux_sys_futex_args *);
int linux_sched_setaffinity(struct thread *, struct linux_sched_setaffinity_args *);
int linux_sched_getaffinity(struct thread *, struct linux_sched_getaffinity_args *);
@@ -2081,6 +2091,7 @@
#define LINUX32_SYS_AUE_linux_lremovexattr AUE_NULL
#define LINUX32_SYS_AUE_linux_fremovexattr AUE_NULL
#define LINUX32_SYS_AUE_linux_tkill AUE_NULL
+#define LINUX32_SYS_AUE_linux_sendfile64 AUE_SENDFILE
#define LINUX32_SYS_AUE_linux_sys_futex AUE_NULL
#define LINUX32_SYS_AUE_linux_sched_setaffinity AUE_NULL
#define LINUX32_SYS_AUE_linux_sched_getaffinity AUE_NULL
Index: sys/amd64/linux32/linux32_syscall.h
===================================================================
--- sys/amd64/linux32/linux32_syscall.h
+++ sys/amd64/linux32/linux32_syscall.h
@@ -216,6 +216,7 @@
#define LINUX32_SYS_linux_lremovexattr 236
#define LINUX32_SYS_linux_fremovexattr 237
#define LINUX32_SYS_linux_tkill 238
+#define LINUX32_SYS_linux_sendfile64 239
#define LINUX32_SYS_linux_sys_futex 240
#define LINUX32_SYS_linux_sched_setaffinity 241
#define LINUX32_SYS_linux_sched_getaffinity 242
Index: sys/amd64/linux32/linux32_syscalls.c
===================================================================
--- sys/amd64/linux32/linux32_syscalls.c
+++ sys/amd64/linux32/linux32_syscalls.c
@@ -246,7 +246,7 @@
"linux_lremovexattr", /* 236 = linux_lremovexattr */
"linux_fremovexattr", /* 237 = linux_fremovexattr */
"linux_tkill", /* 238 = linux_tkill */
- "#239", /* 239 = linux_sendfile64 */
+ "linux_sendfile64", /* 239 = linux_sendfile64 */
"linux_sys_futex", /* 240 = linux_sys_futex */
"linux_sched_setaffinity", /* 241 = linux_sched_setaffinity */
"linux_sched_getaffinity", /* 242 = linux_sched_getaffinity */
Index: sys/amd64/linux32/linux32_sysent.c
===================================================================
--- sys/amd64/linux32/linux32_sysent.c
+++ sys/amd64/linux32/linux32_sysent.c
@@ -204,7 +204,7 @@
{ AS(linux_capget_args), (sy_call_t *)linux_capget, AUE_CAPGET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 184 = linux_capget */
{ AS(linux_capset_args), (sy_call_t *)linux_capset, AUE_CAPSET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 185 = linux_capset */
{ AS(linux_sigaltstack_args), (sy_call_t *)linux_sigaltstack, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 186 = linux_sigaltstack */
- { 0, (sy_call_t *)linux_sendfile, AUE_SENDFILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 187 = linux_sendfile */
+ { AS(linux_sendfile_args), (sy_call_t *)linux_sendfile, AUE_SENDFILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 187 = linux_sendfile */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 188 = getpmsg */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 189 = putpmsg */
{ 0, (sy_call_t *)linux_vfork, AUE_VFORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 190 = linux_vfork */
@@ -256,7 +256,7 @@
{ 0, (sy_call_t *)linux_lremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 236 = linux_lremovexattr */
{ 0, (sy_call_t *)linux_fremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 237 = linux_fremovexattr */
{ AS(linux_tkill_args), (sy_call_t *)linux_tkill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 238 = linux_tkill */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 239 = linux_sendfile64 */
+ { AS(linux_sendfile64_args), (sy_call_t *)linux_sendfile64, AUE_SENDFILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 239 = linux_sendfile64 */
{ AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 240 = linux_sys_futex */
{ AS(linux_sched_setaffinity_args), (sy_call_t *)linux_sched_setaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 241 = linux_sched_setaffinity */
{ AS(linux_sched_getaffinity_args), (sy_call_t *)linux_sched_getaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 242 = linux_sched_getaffinity */
Index: sys/amd64/linux32/linux32_systrace_args.c
===================================================================
--- sys/amd64/linux32/linux32_systrace_args.c
+++ sys/amd64/linux32/linux32_systrace_args.c
@@ -1292,7 +1292,12 @@
}
/* linux_sendfile */
case 187: {
- *n_args = 0;
+ struct linux_sendfile_args *p = params;
+ iarg[0] = p->out; /* l_int */
+ iarg[1] = p->in; /* l_int */
+ uarg[2] = (intptr_t) p->offset; /* l_long * */
+ iarg[3] = p->count; /* l_size_t */
+ *n_args = 4;
break;
}
/* linux_vfork */
@@ -1616,6 +1621,16 @@
*n_args = 2;
break;
}
+ /* linux_sendfile64 */
+ case 239: {
+ struct linux_sendfile64_args *p = params;
+ iarg[0] = p->out; /* l_int */
+ iarg[1] = p->in; /* l_int */
+ uarg[2] = (intptr_t) p->offset; /* l_loff_t * */
+ iarg[3] = p->count; /* l_size_t */
+ *n_args = 4;
+ break;
+ }
/* linux_sys_futex */
case 240: {
struct linux_sys_futex_args *p = params;
@@ -4970,6 +4985,22 @@
break;
/* linux_sendfile */
case 187:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "userland l_long *";
+ break;
+ case 3:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_vfork */
case 190:
@@ -5409,6 +5440,25 @@
break;
};
break;
+ /* linux_sendfile64 */
+ case 239:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "userland l_loff_t *";
+ break;
+ case 3:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
/* linux_sys_futex */
case 240:
switch(ndx) {
@@ -8261,6 +8311,9 @@
break;
/* linux_sendfile */
case 187:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_vfork */
case 190:
/* linux_getrlimit */
@@ -8434,6 +8487,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* linux_sendfile64 */
+ case 239:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_sys_futex */
case 240:
if (ndx == 0 || ndx == 1)
Index: sys/amd64/linux32/syscalls.master
===================================================================
--- sys/amd64/linux32/syscalls.master
+++ sys/amd64/linux32/syscalls.master
@@ -338,7 +338,8 @@
struct l_user_cap_data *datap); }
186 AUE_NULL STD { int linux_sigaltstack(l_stack_t *uss, \
l_stack_t *uoss); }
-187 AUE_SENDFILE STD { int linux_sendfile(void); }
+187 AUE_SENDFILE STD { int linux_sendfile(l_int out, l_int in, \
+ l_long *offset, l_size_t count); }
188 AUE_GETPMSG UNIMPL getpmsg
189 AUE_PUTPMSG UNIMPL putpmsg
190 AUE_VFORK STD { int linux_vfork(void); }
@@ -412,7 +413,8 @@
236 AUE_NULL STD { int linux_lremovexattr(void); }
237 AUE_NULL STD { int linux_fremovexattr(void); }
238 AUE_NULL STD { int linux_tkill(int tid, int sig); }
-239 AUE_SENDFILE UNIMPL linux_sendfile64
+239 AUE_SENDFILE STD { int linux_sendfile64(l_int out, l_int in, \
+ l_loff_t *offset, l_size_t count); }
240 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, uint32_t val, \
struct l_timespec *timeout, uint32_t *uaddr2, uint32_t val3); }
241 AUE_NULL STD { int linux_sched_setaffinity(l_pid_t pid, l_uint len, \
Index: sys/compat/linux/linux_socket.h
===================================================================
--- sys/compat/linux/linux_socket.h
+++ sys/compat/linux/linux_socket.h
@@ -162,6 +162,7 @@
#define LINUX_ACCEPT4 18
#define LINUX_RECVMMSG 19
#define LINUX_SENDMMSG 20
+#define LINUX_SENDFILE 21
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
/* Socket defines */
Index: sys/compat/linux/linux_socket.c
===================================================================
--- sys/compat/linux/linux_socket.c
+++ sys/compat/linux/linux_socket.c
@@ -49,9 +49,12 @@
#include <sys/socketvar.h>
#include <sys/syscallsubr.h>
#include <sys/uio.h>
+#include <sys/stat.h>
#include <sys/syslog.h>
#include <sys/un.h>
+#include <security/audit/audit.h>
+
#include <net/if.h>
#include <net/vnet.h>
#include <netinet/in.h>
@@ -1570,6 +1573,101 @@
return (error);
}
+static int
+linux_sendfile_common(struct thread *td, l_int out, l_int in,
+ l_loff_t *offset, l_size_t count)
+{
+ /* XXX: The differences between freebsd and linux sendfile:
+ * - linux_sendfile doesn't send anything when count is 0
+ * whereas freebsd_sendfile sends the whole file. However,
+ * in linux_sendfile given fds are still checked for if they
+ * are valid or not when count is 0.
+ * - linux_sendfile can send to any fd whereas freebsd_sendfile
+ * only sends to a socket stream. The same restriction follows
+ * for linux_sendfile.
+ * - linux_sendfile doesn't have equivalents of flags and sf_hdtr of
+ * freebsd_sendfile.
+ * - linux_sendfile takes in an offset pointer and updates it to where it
+ * was read until. freebsd_sendfile takes in an offset and a
+ * 'bytes read' parameter which is only filled if it isn't NULL.
+ * We use this parameter to update the offset pointer if it exists.
+ * - linux_sendfile returns bytes read on success while freebsd_sendfile
+ * returns 0. We use the 'bytes read' parameter to get this value.
+ */
+
+ /* YYY: The only difference between sendfile and sendfile64 (for 32bit
+ * platform where LFS is enabled) is offset type. The latter must be
+ * 64 bit
+ */
+
+ struct stat sb;
+ off_t bytes_read;
+ int error;
+ l_loff_t current_offset;
+ struct file *fp;
+
+ /* fstat to get info on target fd */
+ error = kern_fstat(td, out, &sb);
+ if (error < 0)
+ return (error);
+
+ /* offset is assumed as 0 when no pointer is given */
+ current_offset = 0;
+ if (offset != NULL) {
+ error = copyin(offset, ¤t_offset, sizeof(offset));
+ if (error < 0)
+ return (error);
+ }
+
+ if (current_offset < 0)
+ return (EINVAL);
+
+ bytes_read = 0;
+
+ AUDIT_ARG_FD(in);
+ /* check if fdin is valid */
+ error = fget_read(td, in, &cap_pread_rights, &fp);
+ if (error != 0)
+ return (error);
+
+ /* call real sendfile iff count != 0 */
+ if (count != 0) {
+ error = fo_sendfile(fp, out, NULL, NULL, current_offset, count,
+ &bytes_read, 0, td);
+ fdrop(fp, td);
+ if (error < 0)
+ return (error);
+ current_offset += bytes_read;
+ } else {
+ fdrop(fp, td);
+ }
+
+ if (offset != NULL) {
+ error = copyout(¤t_offset, offset, sizeof(current_offset));
+ if (error < 0)
+ return (error);
+ }
+
+ td->td_retval[0] = (ssize_t) bytes_read;
+ return (0);
+}
+
+int
+linux_sendfile(struct thread *td, struct linux_sendfile_args *arg)
+{
+ return linux_sendfile_common(td, arg->out, arg->in,
+ (l_loff_t *)arg->offset, arg->count);
+}
+
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+int
+linux_sendfile64(struct thread *td, struct linux_sendfile64_args *arg)
+{
+ return linux_sendfile_common(td, arg->out, arg->in,
+ arg->offset, arg->count);
+}
+#endif
+
#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
/* Argument list sizes for linux_socketcall */
@@ -1584,7 +1682,7 @@
5 /* setsockopt */, 5 /* getsockopt */,
3 /* sendmsg */, 3 /* recvmsg */,
4 /* accept4 */, 5 /* recvmmsg */,
- 4 /* sendmmsg */
+ 4 /* sendmmsg */, 4 /* sendfile */
};
#define LINUX_ARGS_CNT (nitems(lxs_args_cnt) - 1)
#define LINUX_ARG_SIZE(x) (lxs_args_cnt[x] * sizeof(l_ulong))
@@ -1653,6 +1751,8 @@
return (linux_recvmmsg(td, arg));
case LINUX_SENDMMSG:
return (linux_sendmmsg(td, arg));
+ case LINUX_SENDFILE:
+ return (linux_sendfile(td, arg));
}
uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 21, 9:40 AM (17 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15540053
Default Alt Text
D19917.id66790.diff (13 KB)
Attached To
Mode
D19917: Implement linux_sendfile for the linuxulator
Attached
Detach File
Event Timeline
Log In to Comment