Page MenuHomeFreeBSD

D19917.id66790.diff
No OneTemporary

D19917.id66790.diff

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, &current_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(&current_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

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)

Event Timeline