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
25static void
26check_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 %ld, "
48		    "expected %ld", off64, pos);
49	}
50}
51
52static void
53check_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
66int
67main(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