fix FAST_FUNC fallout
[oweals/busybox.git] / libbb / copyfd.c
index e0596d5f6dde18ed503e6ef81205e196ae09b1ac..c5f8b5b8763a12437be5e74607e5587e67bde9d3 100644 (file)
@@ -9,32 +9,44 @@
 
 #include "libbb.h"
 
-#if BUFSIZ < 4096
-#undef BUFSIZ
-#define BUFSIZ 4096
-#endif
-
-/* Used by NOFORK applets (e.g. cat) - must be very careful
- * when calling xfuncs, allocating memory, with signals, termios, etc... */
+/* Used by NOFORK applets (e.g. cat) - must not use xmalloc */
 
 static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
 {
        int status = -1;
        off_t total = 0;
-       RESERVE_CONFIG_BUFFER(buffer, BUFSIZ);
+#if CONFIG_FEATURE_COPYBUF_KB <= 4
+       char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024];
+       enum { buffer_size = sizeof(buffer) };
+#else
+       char *buffer;
+       int buffer_size;
+
+       /* We want page-aligned buffer, just in case kernel is clever
+        * and can do page-aligned io more efficiently */
+       buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024,
+                       PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_ANON,
+                       /* ignored: */ -1, 0);
+       buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024;
+       if (buffer == MAP_FAILED) {
+               buffer = alloca(4 * 1024);
+               buffer_size = 4 * 1024;
+       }
+#endif
 
        if (src_fd < 0)
                goto out;
 
        if (!size) {
-               size = BUFSIZ;
+               size = buffer_size;
                status = 1; /* copy until eof */
        }
 
        while (1) {
                ssize_t rd;
 
-               rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size);
+               rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size);
 
                if (!rd) { /* eof - all done */
                        status = 0;
@@ -63,22 +75,26 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
                }
        }
  out:
-       RELEASE_CONFIG_BUFFER(buffer);
+
+#if CONFIG_FEATURE_COPYBUF_KB > 4
+       if (buffer_size != 4 * 1024)
+               munmap(buffer, buffer_size);
+#endif
        return status ? -1 : total;
 }
 
 
 #if 0
-void complain_copyfd_and_die(off_t sz)
+void FAST_FUNC complain_copyfd_and_die(off_t sz)
 {
        if (sz != -1)
                bb_error_msg_and_die("short read");
        /* if sz == -1, bb_copyfd_XX already complained */
-       sleep_and_die();
+       xfunc_die();
 }
 #endif
 
-off_t bb_copyfd_size(int fd1, int fd2, off_t size)
+off_t FAST_FUNC bb_copyfd_size(int fd1, int fd2, off_t size)
 {
        if (size) {
                return bb_full_fd_action(fd1, fd2, size);
@@ -86,7 +102,7 @@ off_t bb_copyfd_size(int fd1, int fd2, off_t size)
        return 0;
 }
 
-void bb_copyfd_exact_size(int fd1, int fd2, off_t size)
+void FAST_FUNC bb_copyfd_exact_size(int fd1, int fd2, off_t size)
 {
        off_t sz = bb_copyfd_size(fd1, fd2, size);
        if (sz == size)
@@ -94,10 +110,10 @@ void bb_copyfd_exact_size(int fd1, int fd2, off_t size)
        if (sz != -1)
                bb_error_msg_and_die("short read");
        /* if sz == -1, bb_copyfd_XX already complained */
-       sleep_and_die();
+       xfunc_die();
 }
 
-off_t bb_copyfd_eof(int fd1, int fd2)
+off_t FAST_FUNC bb_copyfd_eof(int fd1, int fd2)
 {
        return bb_full_fd_action(fd1, fd2, 0);
 }