elftc_copyfile.c (276371) | elftc_copyfile.c (295577) |
---|---|
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 | 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 $"); | 40ELFTC_VCSID("$Id: elftc_copyfile.c 3297 2016-01-09 15:26:34Z 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{ | 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 size_t file_size, n; |
|
50 int buf_mmapped; 51 struct stat sb; 52 char *b, *buf; | 51 int buf_mmapped; 52 struct stat sb; 53 char *b, *buf; |
53 ssize_t nw; 54 size_t n; | 54 ssize_t nr, nw; |
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; | 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 file_size = (size_t) sb.st_size; |
|
66 67#if ELFTC_HAVE_MMAP 68 /* 69 * Prefer mmap() if it is available. 70 */ | 67 68#if ELFTC_HAVE_MMAP 69 /* 70 * Prefer mmap() if it is available. 71 */ |
71 buf = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, ifd, (off_t) 0); | 72 buf = mmap(NULL, file_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) { | 73 if (buf != MAP_FAILED) 74 buf_mmapped = 1; 75 else 76 buf = NULL; 77#endif 78 79 /* 80 * If mmap() is not available, or if the mmap() operation 81 * failed, allocate a buffer, and read in input data. 82 */ 83 if (buf_mmapped == false) { |
83 if ((buf = malloc(sb.st_size)) == NULL) | 84 if ((buf = malloc(file_size)) == NULL) |
84 return (-1); | 85 return (-1); |
85 if (read(ifd, buf, sb.st_size) != sb.st_size) { 86 free(buf); 87 return (-1); | 86 b = buf; 87 for (n = file_size; n > 0; n -= (size_t) nr, b += nr) { 88 if ((nr = read(ifd, b, n)) < 0) { 89 free(buf); 90 return (-1); 91 } |
88 } 89 } 90 91 /* 92 * Write data to the output file descriptor. 93 */ | 92 } 93 } 94 95 /* 96 * Write data to the output file descriptor. 97 */ |
94 for (n = sb.st_size, b = buf; n > 0; n -= nw, b += nw) | 98 for (n = file_size, b = buf; n > 0; n -= (size_t) nw, b += nw) |
95 if ((nw = write(ofd, b, n)) <= 0) 96 break; 97 98 /* Release the input buffer. */ 99#if ELFTC_HAVE_MMAP | 99 if ((nw = write(ofd, b, n)) <= 0) 100 break; 101 102 /* Release the input buffer. */ 103#if ELFTC_HAVE_MMAP |
100 if (buf_mmapped && munmap(buf, sb.st_size) < 0) | 104 if (buf_mmapped && munmap(buf, file_size) < 0) |
101 return (-1); 102#endif 103 104 if (!buf_mmapped) 105 free(buf); 106 107 return (n > 0 ? -1 : 0); 108} 109 | 105 return (-1); 106#endif 107 108 if (!buf_mmapped) 109 free(buf); 110 111 return (n > 0 ? -1 : 0); 112} 113 |