tst-ftell-append.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* Verify that ftell returns the correct value after a read and a write on a
  2. file opened in a+ mode.
  3. Copyright (C) 2014-2019 Free Software Foundation, Inc.
  4. This file is part of the GNU C Library.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <errno.h>
  20. #include <unistd.h>
  21. #include <locale.h>
  22. #include <wchar.h>
  23. /* data points to either char_data or wide_data, depending on whether we're
  24. testing regular file mode or wide mode respectively. Similarly,
  25. fputs_func points to either fputs or fputws. data_len keeps track of the
  26. length of the current data and file_len maintains the current file
  27. length. */
  28. #define BUF_LEN 4
  29. static void *buf;
  30. static char char_buf[BUF_LEN];
  31. static wchar_t wide_buf[BUF_LEN];
  32. static const void *data;
  33. static const char *char_data = "abcdefghijklmnopqrstuvwxyz";
  34. static const wchar_t *wide_data = L"abcdefghijklmnopqrstuvwxyz";
  35. static size_t data_len;
  36. static size_t file_len;
  37. typedef int (*fputs_func_t) (const void *data, FILE *fp);
  38. fputs_func_t fputs_func;
  39. typedef void *(*fgets_func_t) (void *s, int size, FILE *stream);
  40. fgets_func_t fgets_func;
  41. static int do_test (void);
  42. #define TEST_FUNCTION do_test ()
  43. #include "../test-skeleton.c"
  44. static FILE *
  45. init_file (const char *filename)
  46. {
  47. FILE *fp = fopen (filename, "w");
  48. if (fp == NULL)
  49. {
  50. printf ("fopen: %m\n");
  51. return NULL;
  52. }
  53. int written = fputs_func (data, fp);
  54. if (written == EOF)
  55. {
  56. printf ("fputs failed to write data\n");
  57. fclose (fp);
  58. return NULL;
  59. }
  60. file_len = data_len;
  61. fclose (fp);
  62. fp = fopen (filename, "a+");
  63. if (fp == NULL)
  64. {
  65. printf ("fopen(a+): %m\n");
  66. return NULL;
  67. }
  68. return fp;
  69. }
  70. static int
  71. do_one_test (const char *filename)
  72. {
  73. FILE *fp = init_file (filename);
  74. if (fp == NULL)
  75. return 1;
  76. void *ret = fgets_func (buf, BUF_LEN, fp);
  77. if (ret == NULL)
  78. {
  79. printf ("read failed: %m\n");
  80. fclose (fp);
  81. return 1;
  82. }
  83. int written = fputs_func (data, fp);
  84. if (written == EOF)
  85. {
  86. printf ("fputs failed to write data\n");
  87. fclose (fp);
  88. return 1;
  89. }
  90. file_len += data_len;
  91. long off = ftell (fp);
  92. if (off != file_len)
  93. {
  94. printf ("Incorrect offset %ld, expected %zu\n", off, file_len);
  95. fclose (fp);
  96. return 1;
  97. }
  98. else
  99. printf ("Correct offset %ld after write.\n", off);
  100. return 0;
  101. }
  102. /* Run the tests for regular files and wide mode files. */
  103. static int
  104. do_test (void)
  105. {
  106. int ret = 0;
  107. char *filename;
  108. int fd = create_temp_file ("tst-ftell-append-tmp.", &filename);
  109. if (fd == -1)
  110. {
  111. printf ("create_temp_file: %m\n");
  112. return 1;
  113. }
  114. close (fd);
  115. /* Tests for regular files. */
  116. puts ("Regular mode:");
  117. fputs_func = (fputs_func_t) fputs;
  118. fgets_func = (fgets_func_t) fgets;
  119. data = char_data;
  120. buf = char_buf;
  121. data_len = strlen (char_data);
  122. ret |= do_one_test (filename);
  123. /* Tests for wide files. */
  124. puts ("Wide mode:");
  125. if (setlocale (LC_ALL, "en_US.UTF-8") == NULL)
  126. {
  127. printf ("Cannot set en_US.UTF-8 locale.\n");
  128. return 1;
  129. }
  130. fputs_func = (fputs_func_t) fputws;
  131. fgets_func = (fgets_func_t) fgetws;
  132. data = wide_data;
  133. buf = wide_buf;
  134. data_len = wcslen (wide_data);
  135. ret |= do_one_test (filename);
  136. return ret;
  137. }