Path: blob/main/contrib/elftoolchain/libelftc/elftc_copyfile.c
39478 views
/*-1* Copyright (c) 2011, Joseph Koshy2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer9* in this position and unchanged.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR15* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES16* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.17* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,18* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT19* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,20* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY21* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT22* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF23* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/2526#include <sys/types.h>27#include <sys/stat.h>2829#include <stdlib.h>30#include <unistd.h>3132#include "libelftc.h"33#include "_libelftc.h"3435#if ELFTC_HAVE_MMAP36#include <sys/mman.h>37#endif3839ELFTC_VCSID("$Id: elftc_copyfile.c 3297 2016-01-09 15:26:34Z jkoshy $");4041/*42* Copy the contents referenced by 'ifd' to 'ofd'. Returns 0 on43* success and -1 on error.44*/4546int47elftc_copyfile(int ifd, int ofd)48{49size_t file_size, n;50int buf_mmapped;51struct stat sb;52char *b, *buf;53ssize_t nr, nw;5455/* Determine the input file's size. */56if (fstat(ifd, &sb) < 0)57return (-1);5859/* Skip files without content. */60if (sb.st_size == 0)61return (0);6263buf = NULL;64buf_mmapped = 0;65file_size = (size_t) sb.st_size;6667#if ELFTC_HAVE_MMAP68/*69* Prefer mmap() if it is available.70*/71buf = mmap(NULL, file_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0);72if (buf != MAP_FAILED)73buf_mmapped = 1;74else75buf = NULL;76#endif7778/*79* If mmap() is not available, or if the mmap() operation80* failed, allocate a buffer, and read in input data.81*/82if (buf_mmapped == false) {83if ((buf = malloc(file_size)) == NULL)84return (-1);85b = buf;86for (n = file_size; n > 0; n -= (size_t) nr, b += nr) {87if ((nr = read(ifd, b, n)) < 0) {88free(buf);89return (-1);90}91}92}9394/*95* Write data to the output file descriptor.96*/97for (n = file_size, b = buf; n > 0; n -= (size_t) nw, b += nw)98if ((nw = write(ofd, b, n)) <= 0)99break;100101/* Release the input buffer. */102#if ELFTC_HAVE_MMAP103if (buf_mmapped && munmap(buf, file_size) < 0)104return (-1);105#endif106107if (!buf_mmapped)108free(buf);109110return (n > 0 ? -1 : 0);111}112113114115