Lely core libraries  2.3.4
io.c
Go to the documentation of this file.
1 
24 #include "io.h"
25 
26 #if !LELY_NO_STDIO
27 
28 #include <lely/util/errnum.h>
29 
30 #include <assert.h>
31 
32 #include "handle.h"
33 
34 static int lely_io_ref;
35 
36 int
38 {
39  if (lely_io_ref++)
40  return 0;
41 
42 #if _WIN32
43  int errc = 0;
44 
45  WORD wVersionRequested = MAKEWORD(2, 2);
46  WSADATA wsaData;
47  if ((errc = WSAStartup(wVersionRequested, &wsaData)))
48  goto error_WSAStartup;
49 #endif
50 
51  return 0;
52 
53 #if _WIN32
54  // WSACleanup();
55 error_WSAStartup:
56  lely_io_ref--;
57  set_errc(errc);
58  return -1;
59 #endif
60 }
61 
62 void
64 {
65  if (lely_io_ref <= 0) {
66  lely_io_ref = 0;
67  return;
68  }
69  if (--lely_io_ref)
70  return;
71 
72 #if _WIN32
73  WSACleanup();
74 #endif
75 }
76 
77 int
79 {
80  if (handle == IO_HANDLE_ERROR) {
82  return -1;
83  }
84 
85  io_handle_release(handle);
86 
87  return 0;
88 }
89 
90 int
92 {
93  if (handle == IO_HANDLE_ERROR) {
95  return -1;
96  }
97 
98  assert(handle->vtab);
99  return handle->vtab->type;
100 }
101 
102 HANDLE
104 {
105  if (handle == IO_HANDLE_ERROR) {
107  return INVALID_HANDLE_VALUE;
108  }
109 
110  return handle->fd;
111 }
112 
113 int
115 {
116  if (handle == IO_HANDLE_ERROR) {
118  return -1;
119  }
120 
121  io_handle_lock(handle);
122  int flags = handle->flags;
123  io_handle_unlock(handle);
124  return flags;
125 }
126 
127 int
128 io_set_flags(io_handle_t handle, int flags)
129 {
130  if (handle == IO_HANDLE_ERROR) {
132  return -1;
133  }
134 
136 
137  int result = 0;
138  io_handle_lock(handle);
139  if (flags != handle->flags) {
140  if (handle->vtab->flags) {
141  result = handle->vtab->flags(handle, flags);
142  if (!result)
143  handle->flags = flags;
144  } else {
146  result = -1;
147  }
148  }
149  io_handle_unlock(handle);
150  return result;
151 }
152 
153 ssize_t
154 io_read(io_handle_t handle, void *buf, size_t nbytes)
155 {
156  if (handle == IO_HANDLE_ERROR) {
158  return -1;
159  }
160 
161  assert(handle->vtab);
162  if (!handle->vtab->read) {
164  return -1;
165  }
166 
167  return handle->vtab->read(handle, buf, nbytes);
168 }
169 
170 ssize_t
171 io_write(io_handle_t handle, const void *buf, size_t nbytes)
172 {
173  if (handle == IO_HANDLE_ERROR) {
175  return -1;
176  }
177 
178  assert(handle->vtab);
179  if (!handle->vtab->write) {
181  return -1;
182  }
183 
184  return handle->vtab->write(handle, buf, nbytes);
185 }
186 
187 int
189 {
190  if (handle == IO_HANDLE_ERROR) {
192  return -1;
193  }
194 
195  assert(handle->vtab);
196  if (!handle->vtab->flush) {
198  return -1;
199  }
200 
201  return handle->vtab->flush(handle);
202 }
203 
204 #endif // !LELY_NO_STDIO
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:200
@ ERRNUM_BADF
Bad file descriptor.
Definition: errnum.h:93
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:424
void io_handle_unlock(struct io_handle *handle)
Unlocks a locked I/O device handle.
Definition: handle.c:151
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:143
This is the internal header file of the I/O handle declarations.
@ 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
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
Definition: io.h:34
void io_handle_release(io_handle_t handle)
Decrements the reference count of an I/O device handle.
Definition: handle.c:51
void lely_io_fini(void)
Finalizes the I/O library and terminates the availability of the I/O functions.
Definition: io.c:63
int io_close(io_handle_t handle)
Closes an I/O device.
Definition: io.c:78
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:91
ssize_t io_read(io_handle_t handle, void *buf, size_t nbytes)
Performs a read operation.
Definition: io.c:154
int lely_io_init(void)
Initializes the I/O library and makes the I/O functions available for use.
Definition: io.c:37
HANDLE io_get_fd(io_handle_t handle)
Returns the native file descriptor of an I/O device.
Definition: io.c:103
int io_flush(io_handle_t handle)
Flushes the write buffer of a an I/O device.
Definition: io.c:188
int io_set_flags(io_handle_t handle, int flags)
Sets the flags of an I/O device.
Definition: io.c:128
int io_get_flags(io_handle_t handle)
Obtains the flags of an I/O device.
Definition: io.c:114
ssize_t io_write(io_handle_t handle, const void *buf, size_t nbytes)
Performs a write operation.
Definition: io.c:171
This is the internal header file of the Windows-specific I/O declarations.
int(* flush)(struct io_handle *handle)
A pointer to the flush method.
Definition: handle.h:84
int(* flags)(struct io_handle *handle, int flags)
A pointer to the static flags method.
Definition: handle.h:77
ssize_t(* write)(struct io_handle *handle, const void *buf, size_t nbytes)
A pointer to the write method.
Definition: handle.h:81
ssize_t(* read)(struct io_handle *handle, void *buf, size_t nbytes)
A pointer to the read method.
Definition: handle.h:79
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:71
An I/O device handle.
Definition: handle.h:33
int fd
The native file descriptor.
Definition: handle.h:48
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
Definition: handle.h:54
const struct io_handle_vtab * vtab
A pointer to the virtual table.
Definition: handle.h:35