[vlc-commits] [Git][videolan/vlc][master] 6 commits: compat: add readv() replacement

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Sun Jul 3 17:49:55 UTC 2022



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
488162f2 by Rémi Denis-Courmont at 2022-07-03T17:31:24+00:00
compat: add readv() replacement

- - - - -
27145e2b by Rémi Denis-Courmont at 2022-07-03T17:31:24+00:00
win32: use readv()

- - - - -
543d179d by Rémi Denis-Courmont at 2022-07-03T17:31:24+00:00
interrupt: deduplicate code

- - - - -
a29ba2f9 by Rémi Denis-Courmont at 2022-07-03T17:31:24+00:00
compat: add writev() replacement

- - - - -
9f18b8fc by Rémi Denis-Courmont at 2022-07-03T17:31:24+00:00
win32: use writev()

- - - - -
d7d51df0 by Rémi Denis-Courmont at 2022-07-03T17:31:24+00:00
interrupt: deduplicate code

- - - - -


6 changed files:

- + compat/readv.c
- + compat/writev.c
- configure.ac
- include/vlc_fixups.h
- src/misc/interrupt.c
- src/win32/filesystem.c


Changes:

=====================================
compat/readv.c
=====================================
@@ -0,0 +1,80 @@
+/*****************************************************************************
+ * readv.c: POSIX readv() replacement
+ *****************************************************************************
+ * Copyright © 2022 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+#endif
+
+ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
+{
+    if (iovcnt == 1)
+        return read(fd, iov->iov_base, iov->iov_len);
+
+    /*
+     * The whole point of readv() is that multiple consecutive reads are *not*
+     * generally equivalent to one read of the same total size. We have to read
+     * all at once to preserve atomicity and packet boundaries.
+     */
+    size_t size = 0;
+
+    for (int i = 0; i < iovcnt; i++) {
+        /* TODO: use ckd_add() */
+        size += iov[i].iov_len;
+
+        if (iov[i].iov_len > size) {
+            errno = EINVAL;
+            return -1;
+        }
+    }
+
+    unsigned char *buf = malloc(size ? size : 1);
+    if (buf == NULL) {
+        errno = ENOBUFS;
+        return -1;
+    }
+
+    ssize_t ret = read(fd, buf, size);
+    int saved_errno = errno;
+
+    for (ssize_t len = ret; len > 0; iov++) {
+        size_t copy = iov->iov_len;
+
+        if (copy > (size_t)len)
+            copy = len;
+
+        memcpy(iov->iov_base, buf, copy);
+        buf += copy;
+        len -= copy;
+    }
+
+    free(buf);
+    errno = saved_errno;
+    return ret;
+}


=====================================
compat/writev.c
=====================================
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * writev.c: POSIX writev() replacement
+ *****************************************************************************
+ * Copyright © 2022 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+#endif
+
+ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
+{
+    if (iovcnt == 1)
+        return write(fd, iov->iov_base, iov->iov_len);
+
+    size_t size = 0;
+
+    for (int i = 0; i < iovcnt; i++) {
+        /* TODO: use ckd_add() */
+        size += iov[i].iov_len;
+
+        if (iov[i].iov_len > size) {
+            errno = EINVAL;
+            return -1;
+        }
+    }
+
+    void *buf = malloc(size ? size : 1);
+    if (buf == NULL) {
+        errno = ENOBUFS;
+        return -1;
+    }
+
+    unsigned char *ptr = buf;
+
+    for (int i = 0; i < iovcnt; i++) {
+        memcpy(ptr, iov->iov_base, iov->iov_len);
+        ptr += iov->iov_len;
+        iov++;
+    }
+
+    ssize_t bytes = write(fd, buf, size);
+    int saved_errno = errno;
+
+    free(buf);
+    errno = saved_errno;
+    return bytes;
+}


=====================================
configure.ac
=====================================
@@ -718,7 +718,7 @@ need_libc=false
 
 dnl Check for usual libc functions
 AC_CHECK_FUNCS([accept4 dup3 fcntl flock fstatat fstatvfs fork getmntent_r getenv getpwuid_r isatty memalign mkostemp mmap open_memstream newlocale pipe2 posix_fadvise setlocale stricmp uselocale wordexp])
-AC_REPLACE_FUNCS([aligned_alloc atof atoll dirfd fdopendir flockfile fsync getdelim getpid lfind lldiv memrchr nrand48 poll posix_memalign recvmsg rewind sendmsg setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strnstr strsep strtof strtok_r strtoll swab tdestroy tfind timegm timespec_get strverscmp])
+AC_REPLACE_FUNCS([aligned_alloc atof atoll dirfd fdopendir flockfile fsync getdelim getpid lfind lldiv memrchr nrand48 poll posix_memalign readv recvmsg rewind sendmsg setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strnstr strsep strtof strtok_r strtoll swab tdestroy tfind timegm timespec_get strverscmp writev])
 AC_REPLACE_FUNCS([gettimeofday])
 AC_CHECK_FUNC(fdatasync,,
   [AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.])


=====================================
include/vlc_fixups.h
=====================================
@@ -226,6 +226,17 @@ float strtof (const char *, char **);
 long long int strtoll (const char *, char **, int);
 #endif
 
+/* sys/uio.h */
+#ifndef HAVE_READV
+struct iovec;
+ssize_t readv(int, const struct iovec *, int);
+#endif
+
+#ifndef HAVE_WRITEV
+struct iovec;
+ssize_t writev(int, const struct iovec *, int);
+#endif
+
 /* time.h */
 #ifndef HAVE_GMTIME_R
 struct tm *gmtime_r (const time_t *, struct tm *);


=====================================
src/misc/interrupt.c
=====================================
@@ -441,6 +441,7 @@ ssize_t vlc_writev_i11e(int fd, const struct iovec *iov, int count)
         return -1;
     return writev(fd, iov, count);
 }
+#endif
 
 /**
  * Wrapper for read() that returns the EINTR error upon VLC I/O interruption.
@@ -465,6 +466,7 @@ ssize_t vlc_write_i11e(int fd, const void *buf, size_t count)
     return vlc_writev_i11e(fd, &iov, 1);
 }
 
+#ifndef _WIN32
 ssize_t vlc_recvmsg_i11e(int fd, struct msghdr *msg, int flags)
 {
     struct pollfd ufd;
@@ -594,24 +596,12 @@ int vlc_poll_i11e(struct pollfd *fds, unsigned nfds, int timeout)
 
 ssize_t vlc_readv_i11e(int fd, struct iovec *iov, int count)
 {
-    (void) fd; (void) iov; (void) count;
-    vlc_assert_unreachable();
+    return readv(fd, iov, count);
 }
 
 ssize_t vlc_writev_i11e(int fd, const struct iovec *iov, int count)
 {
-    (void) fd; (void) iov; (void) count;
-    vlc_assert_unreachable();
-}
-
-ssize_t vlc_read_i11e(int fd, void *buf, size_t count)
-{
-    return read(fd, buf, count);
-}
-
-ssize_t vlc_write_i11e(int fd, const void *buf, size_t count)
-{
-    return write(fd, buf, count);
+    return writev(fd, iov, count);
 }
 
 ssize_t vlc_recvmsg_i11e(int fd, struct msghdr *msg, int flags)


=====================================
src/win32/filesystem.c
=====================================
@@ -329,8 +329,7 @@ ssize_t vlc_write(int fd, const void *buf, size_t len)
 
 ssize_t vlc_writev(int fd, const struct iovec *iov, int count)
 {
-    (void) fd; (void) iov; (void) count;
-    vlc_assert_unreachable();
+    return writev(fd, iov, count);
 }
 
 #include <vlc_network.h>



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9979f075c9b538dffd56d30e9571a9878a0a3bbd...d7d51df095b1883d40856c5c315280dec495ea7a

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9979f075c9b538dffd56d30e9571a9878a0a3bbd...d7d51df095b1883d40856c5c315280dec495ea7a
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list