blob: 05bed6b733a8f49c624f721c7275a54e0c23d170 [file] [log] [blame]
Eric Andersen55f98722001-05-15 17:48:09 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
Eric Andersencb81e642003-07-14 21:21:08 +00005 * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
Eric Andersen55f98722001-05-15 17:48:09 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <unistd.h>
23#include <string.h>
24#include <errno.h>
Manuel Novoa III cad53642003-03-19 09:13:01 +000025#include "busybox.h"
Eric Andersen55f98722001-05-15 17:48:09 +000026
Manuel Novoa III cad53642003-03-19 09:13:01 +000027#if BUFSIZ < 4096
28#undef BUFSIZ
29#define BUFSIZ 4096
30#endif
31
32/* If chunksize is 0 copy until EOF */
33extern int bb_copyfd(int fd1, int fd2, const off_t chunksize)
Eric Andersen55f98722001-05-15 17:48:09 +000034{
Manuel Novoa III cad53642003-03-19 09:13:01 +000035 ssize_t nread;
Glenn L McGrath25fe94f2002-12-13 08:20:44 +000036 size_t size;
Manuel Novoa III cad53642003-03-19 09:13:01 +000037 off_t remaining;
38 RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
Eric Andersen55f98722001-05-15 17:48:09 +000039
Manuel Novoa III cad53642003-03-19 09:13:01 +000040 remaining = size = BUFSIZ;
Glenn L McGrath25fe94f2002-12-13 08:20:44 +000041 if (chunksize) {
42 remaining = chunksize;
Eric Andersen55f98722001-05-15 17:48:09 +000043 }
Matt Kraaid6ef0742001-05-18 14:14:55 +000044
Glenn L McGrath25fe94f2002-12-13 08:20:44 +000045 do {
Manuel Novoa III cad53642003-03-19 09:13:01 +000046 if (size > remaining) {
47 size = remaining;
Glenn L McGrath25fe94f2002-12-13 08:20:44 +000048 }
49
Manuel Novoa III cad53642003-03-19 09:13:01 +000050 if ((nread = safe_read(fd1, buffer, size)) > 0) {
51 if (bb_full_write(fd2, buffer, nread) < 0) {
52 bb_perror_msg(bb_msg_write_error); /* match Read error below */
53 break;
Glenn L McGrath25fe94f2002-12-13 08:20:44 +000054 }
Manuel Novoa III cad53642003-03-19 09:13:01 +000055 if (chunksize && ((remaining -= nread) == 0)) {
56 return 0;
57 }
58 } else if (!nread) {
59 if (chunksize) {
60 bb_error_msg("Unable to read all data");
61 break;
62 }
63 return 0;
64 } else { /* nread < 0 */
65 bb_perror_msg("Read error"); /* match bb_msg_write_error above */
66 break;
Glenn L McGrath25fe94f2002-12-13 08:20:44 +000067 }
68
Manuel Novoa III cad53642003-03-19 09:13:01 +000069 } while (1);
Glenn L McGrath25fe94f2002-12-13 08:20:44 +000070
Manuel Novoa III cad53642003-03-19 09:13:01 +000071 return -1;
Eric Andersen55f98722001-05-15 17:48:09 +000072}