1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
.TH MPU_FOPEN 3 "August 2026" "libmpuio" "LIBMPUIO Programmer's Manual"
.SH NAME
mpu_fopen, mpu_fdopen, mpu_fclose, mpu_fflush, mpu_flushlbf, mpu_fileno \- open, attach, close and synchronize LIBMPUIO streams
.SH SYNOPSIS
.nf
#include <libmpuio.h>
mpu_FILE *mpu_fopen( const char *filename, const char *mode );
mpu_FILE *mpu_fdopen( int fd, const char *mode );
int mpu_fclose( mpu_FILE *stream );
int mpu_fflush( mpu_FILE *stream );
void mpu_flushlbf( void );
int mpu_fileno( mpu_FILE *stream );
.fi
.SH DESCRIPTION
.B mpu_fopen
opens the UTF-8 pathname named by
.I filename
using the ISO C stdio mode grammar. The first character is exactly one of
.B r
(read an existing file),
.B w
(create or truncate for writing), or
.B a
(create if necessary and append every write). At most one
.B +
(update: both reading and writing) and at most one
.B b
(binary spelling) may follow, in either order. Thus r, rb, r+, rb+, r+b
and the corresponding w and a forms are accepted. Since LIBMPUIO raw byte
I/O and UTF-8 text conversion are explicit operations, b does not alter the
underlying POSIX descriptor semantics. Unknown, duplicated, or misplaced
mode characters are rejected with EINVAL.
.B mpu_fdopen
attaches an existing POSIX descriptor. The requested read/write access must
be compatible with the descriptor access mode. Append mode enables O_APPEND
when necessary. After successful attachment the descriptor belongs to the
stream and is closed by
.BR mpu_fclose .
.PP
.B mpu_fflush
synchronizes a stream. With a null argument it flushes all currently linked
streams that are actively writing. This includes descriptor and cookie
output/update streams and publishes an actively writing
.BR mpu_open_memstream (3)
stream.
.PP
.B mpu_flushlbf
is the LIBMPUIO counterpart of the glibc _flushlbf() extension. It visits the
current global stream list and synchronizes only streams that are both actively
writing and configured for line buffering with MPU_IOLBF. Fully buffered and
unbuffered streams are not selected merely because they are writable.
Failures do not stop traversal of later line-buffered streams. Because the
interface has no return value, errno from the first failed synchronization is
retained; when every selected synchronization succeeds, the caller's incoming
errno value is preserved.
.B mpu_fileno
returns the POSIX descriptor of a real-file stream. The ordinary form holds
the stream mutex while reading descriptor state; mpu_fileno_unlocked() omits
that lock.
.SH RETURN VALUE
Open functions return a stream pointer or NULL. Close/flush return zero on
success and
.B mpu_EOF
on failure. mpu_flushlbf has no return value. mpu_fileno returns a descriptor
or -1.
.PP
If pending buffered output cannot be written while mpu_fclose() is closing a
stream, mpu_fclose() still closes and releases the stream but returns
.B mpu_EOF
and preserves the errno value from the flush failure.
.SH ERRORS
Failures set
.B errno
as appropriate. EINVAL is used for invalid modes and incompatible operations;
EBADF is used for invalid descriptors and non-file streams where applicable.
.SH LOCKING AND THREADING
The ordinary functions in this family are synchronized. Successful
.BR mpu_fdopen ()
transfers descriptor ownership to the stream; after that point the application
must not independently close the descriptor while the stream is live.
.PP
.BR mpu_fclose ()
is a lifetime operation. Application code must synchronize it against any
other direct use of the same stream pointer. Internally, close and
.B mpu_fflush(NULL)
use the global-list-before-stream lock order so an all-stream traversal cannot
observe a half-destroyed stream. mpu_flushlbf() uses the same lock order.
.SH LOCKED AND UNLOCKED FORMS
.BR mpu_fflush_unlocked ()
and
.BR mpu_fileno_unlocked ()
omit the stream mutex. They are suitable only under an explicit
.BR mpu_flockfile (3)
or equivalent external synchronization. There is no unlocked fopen, fdopen,
or fclose operation.
.PP
Unlike
.BR mpu_fflush (),
the unlocked flush requires a non-NULL stream and never means "flush all
streams".
.SH NOTES
Mode strings are deliberately strict: the first character is r, w, or a,
followed by at most one + and at most one b in either order. Unknown,
repeated, or misplaced mode characters are rejected with EINVAL.
.SH SEE ALSO
.BR libmpuio (3),
.BR mpu_freopen (3),
.BR mpu_tmpfile (3),
.BR mpu_fmemopen (3),
.BR mpu_fseek (3),
.BR mpu_setvbuf (3),
.BR mpu_fpurge (3)
.SH ALL-STREAM FLUSH ERRORS
.B mpu_fflush(NULL)
attempts to synchronize every linked stream that currently has pending output.
A failure on one stream does not prevent later streams from being visited.
If one or more streams fail, the function returns
.B mpu_EOF
and restores
.B errno
from the first failed stream.
.SH CONCURRENT ALL-STREAM FLUSH AND CLOSE
The global stream list is serialized with a dedicated internal mutex. Its
lock order is defined before an individual stream lock. mpu_fclose() removes
the stream from the global list while holding both locks and only then begins
the close operation. Therefore a concurrent mpu_fflush(NULL) sees either the
fully live stream or no stream at all; it does not traverse a half-closed
stream and cannot race the stream object's destruction.
.PP
This lifetime guarantee applies to the library's global-list operations. It
does not make arbitrary concurrent use of the same mpu_FILE pointer after or
during mpu_fclose() valid; applications must still synchronize ownership of a
stream being explicitly closed.
.SH LINE-BUFFERED ALL-STREAM FLUSH
.B mpu_flushlbf()
uses the same global stream-list lifetime discipline as mpu_fflush(NULL), but
selects only streams whose state is both WRITING and MPU_IOLBF. It is useful
when an application needs to publish pending line-buffered text without
forcing unrelated fully buffered output to the underlying backend. The
operation is backend-independent and therefore also applies to line-buffered
cookie streams.
|