Commit 3ce34dfb42e02225f2688ef8ad4b9664a4c98e46
Committed by
Riku Voipio
1 parent
099d6b0f
linux-user: add tee, splice and vmsplice
Add support for tee, splice and vmsplice. Originally from: vibi sreenivasan <vibi_sreenivasan@cms.com> Riku: squashed patches together, added a test to configure and removed compliler warning by picking up correct type for splice param Signed-off-by: vibisreenivasan <vibi_sreenivasan@cms.com> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Showing
2 changed files
with
63 additions
and
0 deletions
configure
... | ... | @@ -1322,6 +1322,26 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then |
1322 | 1322 | pipe2=yes |
1323 | 1323 | fi |
1324 | 1324 | |
1325 | +# check if tee/splice is there. vmsplice was added same time. | |
1326 | +splice=no | |
1327 | +cat > $TMPC << EOF | |
1328 | +#define _GNU_SOURCE | |
1329 | +#include <unistd.h> | |
1330 | +#include <fcntl.h> | |
1331 | +#include <limits.h> | |
1332 | + | |
1333 | +int main(void) | |
1334 | +{ | |
1335 | + int len, fd; | |
1336 | + len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); | |
1337 | + splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); | |
1338 | + return 0; | |
1339 | +} | |
1340 | +EOF | |
1341 | +if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then | |
1342 | + splice=yes | |
1343 | +fi | |
1344 | + | |
1325 | 1345 | # Check if tools are available to build documentation. |
1326 | 1346 | if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then |
1327 | 1347 | build_docs="no" |
... | ... | @@ -1725,6 +1745,9 @@ fi |
1725 | 1745 | if test "$pipe2" = "yes" ; then |
1726 | 1746 | echo "#define CONFIG_PIPE2 1" >> $config_h |
1727 | 1747 | fi |
1748 | +if test "$splice" = "yes" ; then | |
1749 | + echo "#define CONFIG_SPLICE 1" >> $config_h | |
1750 | +fi | |
1728 | 1751 | if test "$inotify" = "yes" ; then |
1729 | 1752 | echo "#define CONFIG_INOTIFY 1" >> $config_h |
1730 | 1753 | fi | ... | ... |
linux-user/syscall.c
... | ... | @@ -6865,6 +6865,46 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
6865 | 6865 | break; |
6866 | 6866 | #endif |
6867 | 6867 | |
6868 | +#ifdef CONFIG_SPLICE | |
6869 | +#ifdef TARGET_NR_tee | |
6870 | + case TARGET_NR_tee: | |
6871 | + { | |
6872 | + ret = get_errno(tee(arg1,arg2,arg3,arg4)); | |
6873 | + } | |
6874 | + break; | |
6875 | +#endif | |
6876 | +#ifdef TARGET_NR_splice | |
6877 | + case TARGET_NR_splice: | |
6878 | + { | |
6879 | + loff_t loff_in, loff_out; | |
6880 | + loff_t *ploff_in = NULL, *ploff_out = NULL; | |
6881 | + if(arg2) { | |
6882 | + get_user_u64(loff_in, arg2); | |
6883 | + ploff_in = &loff_in; | |
6884 | + } | |
6885 | + if(arg4) { | |
6886 | + get_user_u64(loff_out, arg2); | |
6887 | + ploff_out = &loff_out; | |
6888 | + } | |
6889 | + ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6)); | |
6890 | + } | |
6891 | + break; | |
6892 | +#endif | |
6893 | +#ifdef TARGET_NR_vmsplice | |
6894 | + case TARGET_NR_vmsplice: | |
6895 | + { | |
6896 | + int count = arg3; | |
6897 | + struct iovec *vec; | |
6898 | + | |
6899 | + vec = alloca(count * sizeof(struct iovec)); | |
6900 | + if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) | |
6901 | + goto efault; | |
6902 | + ret = get_errno(vmsplice(arg1, vec, count, arg4)); | |
6903 | + unlock_iovec(vec, arg2, count, 0); | |
6904 | + } | |
6905 | + break; | |
6906 | +#endif | |
6907 | +#endif /* CONFIG_SPLICE */ | |
6868 | 6908 | default: |
6869 | 6909 | unimplemented: |
6870 | 6910 | gemu_log("qemu: Unsupported syscall: %d\n", num); | ... | ... |