Lely core libraries 1.9.2
io.c
Go to the documentation of this file.
1
24#include "io.h"
25#include "handle.h"
26#include <lely/util/errnum.h>
27
28#include <assert.h>
29
30static int lely_io_ref;
31
32int
34{
35 if (lely_io_ref++)
36 return 0;
37
38 int errc = 0;
39
40#ifdef _WIN32
41 WORD wVersionRequested = MAKEWORD(2, 2);
42 WSADATA wsaData;
43 if (__unlikely(errc = WSAStartup(wVersionRequested, &wsaData)))
44 goto error_WSAStartup;
45#endif
46
47 return 0;
48
49#ifdef _WIN32
50 WSACleanup();
51error_WSAStartup:
52#endif
53 lely_io_ref--;
54 set_errc(errc);
55 return -1;
56}
57
58void
60{
61 if (__unlikely(lely_io_ref <= 0)) {
62 lely_io_ref = 0;
63 return;
64 }
65 if (--lely_io_ref)
66 return;
67
68#ifdef _WIN32
69 WSACleanup();
70#endif
71}
72
73int
75{
76 if (__unlikely(handle == IO_HANDLE_ERROR)) {
78 return -1;
79 }
80
81 io_handle_release(handle);
82
83 return 0;
84}
85
86int
88{
89 if (__unlikely(handle == IO_HANDLE_ERROR)) {
91 return -1;
92 }
93
94 assert(handle->vtab);
95 return handle->vtab->type;
96}
97
98HANDLE
100{
101 if (__unlikely(handle == IO_HANDLE_ERROR)) {
103 return INVALID_HANDLE_VALUE;
104 }
105
106 return handle->fd;
107}
108
109int
111{
112 if (__unlikely(handle == IO_HANDLE_ERROR)) {
114 return -1;
115 }
116
117 io_handle_lock(handle);
118 int flags = handle->flags;
119 io_handle_unlock(handle);
120 return flags;
121}
122
123int
124io_set_flags(io_handle_t handle, int flags)
125{
126 if (__unlikely(handle == IO_HANDLE_ERROR)) {
128 return -1;
129 }
130
132
133 int result = 0;
134 io_handle_lock(handle);
135 if (flags != handle->flags) {
136 if (__likely(handle->vtab->flags)) {
137 result = handle->vtab->flags(handle, flags);
138 if (__likely(!result))
139 handle->flags = flags;
140 } else {
142 result = -1;
143 }
144 }
145 io_handle_unlock(handle);
146 return result;
147}
148
150io_read(io_handle_t handle, void *buf, size_t nbytes)
151{
152 if (__unlikely(handle == IO_HANDLE_ERROR)) {
154 return -1;
155 }
156
157 assert(handle->vtab);
158 if (__unlikely(!handle->vtab->read)) {
160 return -1;
161 }
162
163 return handle->vtab->read(handle, buf, nbytes);
164}
165
167io_write(io_handle_t handle, const void *buf, size_t nbytes)
168{
169 if (__unlikely(handle == IO_HANDLE_ERROR)) {
171 return -1;
172 }
173
174 assert(handle->vtab);
175 if (__unlikely(!handle->vtab->write)) {
177 return -1;
178 }
179
180 return handle->vtab->write(handle, buf, nbytes);
181}
182
183int
185{
186 if (__unlikely(handle == IO_HANDLE_ERROR)) {
188 return -1;
189 }
190
191 assert(handle->vtab);
192 if (__unlikely(!handle->vtab->flush)) {
194 return -1;
195 }
196
197 return handle->vtab->flush(handle);
198}
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_NXIO
No such device or address.
Definition: errnum.h:197
@ ERRNUM_BADF
Bad file descriptor.
Definition: errnum.h:90
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:957
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:375
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
Definition: features.h:286
#define __likely(x)
Indicates to the compiler that the expression is most-likely true.
Definition: features.h:273
void io_handle_unlock(struct io_handle *handle)
Unlocks a locked I/O device handle.
Definition: handle.c:147
void io_handle_lock(struct io_handle *handle)
Locks an unlocked I/O device handle, so the flags (and other device-specific fields) can safely be ac...
Definition: handle.c:139
This is the internal header file of the I/O handle declarations.
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
Definition: io.h:34
@ IO_FLAG_NONBLOCK
Perform I/O operations in non-blocking mode.
Definition: io.h:62
@ IO_FLAG_LOOPBACK
Receive own messages (i.e., sent by the same device).
Definition: io.h:64
@ IO_FLAG_NO_CLOSE
Do not close the native file descriptor when closing an I/O device.
Definition: io.h:60
void io_handle_release(io_handle_t handle)
Decrements the reference count of an I/O device handle.
Definition: handle.c:47
void lely_io_fini(void)
Finalizes the I/O library and terminates the availability of the I/O functions.
Definition: io.c:59
int io_close(io_handle_t handle)
Closes an I/O device.
Definition: io.c:74
int io_get_type(io_handle_t handle)
Returns the type of an I/O device (one of IO_TYPE_CAN, IO_TYPE_FILE, IO_TYPE_PIPE,...
Definition: io.c:87
ssize_t io_read(io_handle_t handle, void *buf, size_t nbytes)
Performs a read operation.
Definition: io.c:150
int lely_io_init(void)
Initializes the I/O library and makes the I/O functions available for use.
Definition: io.c:33
HANDLE io_get_fd(io_handle_t handle)
Returns the native file descriptor of an I/O device.
Definition: io.c:99
int io_flush(io_handle_t handle)
Flushes the write buffer of a an I/O device.
Definition: io.c:184
int io_set_flags(io_handle_t handle, int flags)
Sets the flags of an I/O device.
Definition: io.c:124
int io_get_flags(io_handle_t handle)
Obtains the flags of an I/O device.
Definition: io.c:110
ssize_t io_write(io_handle_t handle, const void *buf, size_t nbytes)
Performs a write operation.
Definition: io.c:167
This is the internal header file of the I/O library.
int(* flush)(struct io_handle *handle)
A pointer to the flush method.
Definition: handle.h:92
int(* flags)(struct io_handle *handle, int flags)
A pointer to the static flags method.
Definition: handle.h:85
ssize_t(* write)(struct io_handle *handle, const void *buf, size_t nbytes)
A pointer to the write method.
Definition: handle.h:89
ssize_t(* read)(struct io_handle *handle, void *buf, size_t nbytes)
A pointer to the read method.
Definition: handle.h:87
int type
The type of the device (one of IO_TYPE_CAN, IO_TYPE_FILE, IO_TYPE_PIPE, IO_TYPE_SERIAL or IO_TYPE_SOC...
Definition: handle.h:79
An I/O device handle.
Definition: handle.h:41
int fd
The native file descriptor.
Definition: handle.h:56
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
Definition: handle.h:62
const struct io_handle_vtab * vtab
A pointer to the virtual table.
Definition: handle.h:43
ptrdiff_t ssize_t
Used for a count of bytes or an error indication.
Definition: types.h:43