C Application For File Copying Using stat(), posix_fadvise()

Here is a simple C example that demonstrates using stat(), posix_fadvise() and assert() for a file copy, not that its not great for sparse files, but this example is! ;)

  1. /**
  2. * @file cpy.c
  3. * @author Ron Brash ([email protected]
  4. * @date Sept 12, 2014
  5. * @brief Simple C program demonstrating posix fadvise for a file
  6. * copy application
  7. */
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <error.h>
  13. #include <string.h>
  14.  
  15. #include <assert.h>
  16.  
  17. #define BUF_SIZE 8192 // 8k ;)
  18.  
  19. static off_t fsize(const char *filename);
  20.  
  21. /**
  22. * fsize(const char *filename)
  23. *
  24. * @brief Returns the filesize of a file using stat.h
  25. * @param filename
  26. * @return -1 if there is an error, zero or positive value otherwise
  27. */
  28. static off_t fsize(const char *filename)
  29. {
  30. struct stat st = { 0 };
  31.  
  32. if (stat(filename, &st) == 0) {
  33.  
  34. return st.st_size;
  35. }
  36.  
  37. return (-1);
  38. }
  39.  
  40. int main(int argc, char **argv)
  41. {
  42. int inputFD = 0;
  43. int outputFD = 0;
  44. char buf[8192] = { };
  45. ssize_t file_size = 0;
  46.  
  47. /* Open a file descriptor for the input file */
  48. if ((inputFD = open(argv[1], O_RDONLY)) == -1) {
  49. perror("Error opening input file descriptor");
  50. return (-1);
  51. }
  52.  
  53. /* Determine the file_size of the input file */
  54. if ((file_size = fsize(argv[1])) < 0) {
  55. perror("Unable to determine accurate size of file");
  56. return (-1);
  57. }
  58.  
  59. /* Open a file descriptor for the output file */
  60. if ((outputFD = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, S_IRUSR | S_IWUSR)) == -1) {
  61. perror("Error opening output file descriptor");
  62. return (-1);
  63. }
  64.  
  65. /* Lets advise the kernel that we are going to attempt a long
  66. * sequential write */
  67. if (posix_fadvise(inputFD, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) {
  68. perror("Unable to advise the kernel for the upcoming sequential write");
  69. // Continue anyways...
  70. }
  71.  
  72. /* Read from the input file descriptor and write to the output file descriptor
  73. * while keeping the 8k within the CPUs L1 cache */
  74. while (1) {
  75. file_size = read(inputFD, &buf[0], sizeof(buf));
  76. if (!file_size) {
  77. break;
  78. }
  79. assert(file_size > 0);
  80. assert(write(outputFD, &buf[0], file_size) == file_size);
  81.  
  82. }
  83.  
  84. /* Close the input file descriptor */
  85. if (close(inputFD) == -1) {
  86. perror("closing inputFD");
  87. return (-1);
  88. }
  89.  
  90. /* Close the output file descriptor */
  91. if (close(outputFD) == -1) {
  92. perror("closing outputFD");
  93. return (-1);
  94. }
  95.  
  96. return 0;
  97. }

Blog tags: 

AttachmentSize
cpy.c2.18 KB

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.