[vlc-devel] [PATCH 1/2] compat: Workaround sendmsg bug on some ArmV8 Android devices
Thomas Guillem
thomas at gllm.fr
Fri Mar 29 13:38:38 CET 2019
On Fri, Mar 29, 2019, at 11:35, Hugo Beauzée-Luyssen wrote:
> On some devices (at least up to Android 6) sendmsg will return its error
> code on 32bits instead of 64.
Sad... Android 6 will still be supported by VLC 4.0, so we need the work-around for 4.0 and 3.0.
> Most likely some code is storing the ssize_t on a size_t, getting rid of
> the sign bit and therefore of the sign extension afterward.
> This causes us to use 0xFFFFFFFF as a very large number of bytes instead
> of an error.
> This patch works around the issue and assumes that 0xFFFFFFFF with a non
> 0 errno is an error and forces it to be returned on 64bits.
> ---
> compat/sendmsg.c | 24 ++++++++++++++++++++++++
> configure.ac | 3 +++
> include/vlc_network.h | 6 ++++++
> 3 files changed, 33 insertions(+)
>
> diff --git a/compat/sendmsg.c b/compat/sendmsg.c
> index 0b08ce0942..2ef542eb7b 100644
> --- a/compat/sendmsg.c
> +++ b/compat/sendmsg.c
> @@ -133,6 +133,30 @@ ssize_t sendmsg(int fd, const struct msghdr *msg,
> int flags)
> free(data);
> return res;
> }
> +#elif defined(__ANDROID__) && defined(__aarch64__)
> +
> +#undef sendmsg
> +
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +
> +/**
> + * Since we bumped the NDK version from 14 to 18, some devices (at
> least up to
> + * Android 6) are returning errors on 4 bytes, even though ssize_t is
> actually
> + * 8 bytes. This causes `value < 0` checks to yield false, and
> consider the value
> + * as a non error.
> + * As the patch lies in either the NDK or the Android kernel, or the
> device libc
> + * we can only work around it. If errno is not 0 & we receive -1, on
> 32bits or
> + * 64bits, we assume an error was returned.
> + */
> +ssize_t vlc_sendmsg(int fd, const struct msghdr *msg, int flags)
> +{
> + errno = 0;
> + ssize_t ret = sendmsg(fd, msg, flags);
> + if ((ret < 0 || ret == 0xFFFFFFFF) && errno != 0)
> + return -1;
> + return ret;
> +}
I don't think this a good place for a vlc_ function. Indeed, the compat/ folder contains only functions with the original prototype.
>
> #else
> #error sendmsg not implemented on your platform!
> diff --git a/configure.ac b/configure.ac
> index 1bd42678b8..0bb12f4305 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -402,6 +402,9 @@ AS_IF([test "$SYS" = linux],[
> ],[
> HAVE_ANDROID="1"
> AC_MSG_RESULT([yes])
> + AS_IF([test "${host_cpu}" = "aarch64"], [
> + AC_LIBOBJ([sendmsg])
> + ])
> ],[
> AC_MSG_RESULT([no])
> ])
> diff --git a/include/vlc_network.h b/include/vlc_network.h
> index 7cc384587a..d75905ea3f 100644
> --- a/include/vlc_network.h
> +++ b/include/vlc_network.h
> @@ -280,6 +280,12 @@ static inline int net_GetPeerAddress( int fd, char
> *address, int *port )
>
> VLC_API char *vlc_getProxyUrl(const char *);
>
> +#if defined(__ANDROID__) && defined(__aarch64__)
> +struct msghdr;
> +ssize_t vlc_sendmsg(int fd, const struct msghdr *msg, int flags);
> +#define sendmsg(a, b, c) vlc_sendmsg(a,b,c)
> +#endif
Maybe put it here in a static inline ?
> +
> # ifdef __cplusplus
> }
> # endif
> --
> 2.20.1
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list