Deleted Added
sdiff udiff text old ( 276371 ) new ( 295577 )
full compact
1/*-
2 * Copyright (c) 2011, Joseph Koshy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 23 unchanged lines hidden (view full) ---

32
33#include "libelftc.h"
34#include "_libelftc.h"
35
36#if ELFTC_HAVE_MMAP
37#include <sys/mman.h>
38#endif
39
40ELFTC_VCSID("$Id: elftc_copyfile.c 2981 2014-02-01 02:41:13Z jkoshy $");
41
42/*
43 * Copy the contents referenced by 'ifd' to 'ofd'. Returns 0 on
44 * success and -1 on error.
45 */
46
47int
48elftc_copyfile(int ifd, int ofd)
49{
50 int buf_mmapped;
51 struct stat sb;
52 char *b, *buf;
53 ssize_t nw;
54 size_t n;
55
56 /* Determine the input file's size. */
57 if (fstat(ifd, &sb) < 0)
58 return (-1);
59
60 /* Skip files without content. */
61 if (sb.st_size == 0)
62 return (0);
63
64 buf = NULL;
65 buf_mmapped = 0;
66
67#if ELFTC_HAVE_MMAP
68 /*
69 * Prefer mmap() if it is available.
70 */
71 buf = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0);
72 if (buf != MAP_FAILED)
73 buf_mmapped = 1;
74 else
75 buf = NULL;
76#endif
77
78 /*
79 * If mmap() is not available, or if the mmap() operation
80 * failed, allocate a buffer, and read in input data.
81 */
82 if (buf_mmapped == false) {
83 if ((buf = malloc(sb.st_size)) == NULL)
84 return (-1);
85 if (read(ifd, buf, sb.st_size) != sb.st_size) {
86 free(buf);
87 return (-1);
88 }
89 }
90
91 /*
92 * Write data to the output file descriptor.
93 */
94 for (n = sb.st_size, b = buf; n > 0; n -= nw, b += nw)
95 if ((nw = write(ofd, b, n)) <= 0)
96 break;
97
98 /* Release the input buffer. */
99#if ELFTC_HAVE_MMAP
100 if (buf_mmapped && munmap(buf, sb.st_size) < 0)
101 return (-1);
102#endif
103
104 if (!buf_mmapped)
105 free(buf);
106
107 return (n > 0 ? -1 : 0);
108}
109