1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2020 Robert Mustacchi
14 */
15
16 /*
17 * Regression test for illumos#12392. Here, ftello64 didn't correctly handle an
18 * ungetc() in the write path when it was unbuffered.
19 */
20
21 #include <stdio.h>
22 #include <err.h>
23 #include <stdlib.h>
24
25 static void
check_pos(FILE * f,long pos)26 check_pos(FILE *f, long pos)
27 {
28 long l;
29 off_t off;
30 off64_t off64;
31
32 l = ftell(f);
33 off = ftello(f);
34 off64 = ftello64(f);
35
36 if (l != pos) {
37 errx(EXIT_FAILURE, "ftell position mismatched: found %ld, "
38 "expected %ld", l, pos);
39 }
40
41 if (off != pos) {
42 errx(EXIT_FAILURE, "ftello position mismatched: found %ld, "
43 "expected %ld", off, pos);
44 }
45
46 if (off64 != pos) {
47 errx(EXIT_FAILURE, "ftello64 position mismatched: found %"
48 PRId64 " expected %ld", off64, pos);
49 }
50 }
51
52 static void
check_one(FILE * f)53 check_one(FILE *f)
54 {
55 if (fputc('a', f) != 'a') {
56 err(EXIT_FAILURE, "failed to write character");
57 }
58 check_pos(f, 1);
59
60 if (ungetc('b', f) != 'b') {
61 err(EXIT_FAILURE, "failed to unget character");
62 }
63 check_pos(f, 0);
64 }
65
66 int
main(void)67 main(void)
68 {
69 FILE *f;
70
71 f = tmpfile();
72 if (f == NULL) {
73 err(EXIT_FAILURE, "failed to create temproary "
74 "file");
75 }
76
77 if (setvbuf(f, NULL, _IONBF, 0) != 0) {
78 err(EXIT_FAILURE, "failed to set non-buffering mode");
79 }
80 check_one(f);
81 if (fclose(f) != 0) {
82 err(EXIT_FAILURE, "failed to close temporary file");
83 }
84
85 return (0);
86 }
87