32#define IO_StopRdWr (IO_StopRd | IO_StopWr)
56 void *Data1,
void *Data2);
66 IOData_t *io =
dNew0(IOData_t, 1);
85 _MSG(
"IO_ins: io->Key=%d, Klist_length=%d\n",
129 _MSG(
"====> begin IO_close_fd (%d) Key=%d CloseCode=%d ",
130 io->FD, io->Key, CloseCode);
137 _MSG(
" NOT CLOSING ");
151 _MSG(
" end IO close (%d) <=====\n", io->FD);
162 int io_key = io->Key;
178 if (errno == EINTR) {
180 }
else if (errno == EAGAIN) {
189 MSG(
"READ Failed with %d: %s\n", (
int)St, strerror(errno));
198 if (io->Buf->len > 0) {
207 if ((io =
IO_get(io_key))) {
209 _MSG(
"IO_read: io->Key=%d io_key=%d\n", io->Key, io_key);
229 St = conn ?
a_Tls_write(conn, io->Buf->str, io->Buf->len)
230 : write(io->FD, io->Buf->str, io->Buf->len);
233 if (errno == EINTR) {
235 }
else if (errno == EAGAIN) {
244 MSG(
"WRITE Failed with %d: %s\n", (
int)St, strerror(errno));
248 }
else if (St < io->Buf->len) {
269 _MSG(
"IO_callback:: (%s) FD = %d\n",
270 (io->Op ==
IORead) ?
"IORead" :
"IOWrite", io->FD);
274 }
else if (io->Op ==
IOWrite) {
277 return (ret) ? 1 : 0;
286 IOData_t *io =
IO_get(io_key);
290 MSG_ERR(
"IO_fd_read_cb: call on already closed io!\n");
296 if ((io =
IO_get(io_key)) && io->Status) {
309 IOData_t *io =
IO_get(io_key);
313 MSG_ERR(
"IO_fd_write_cb: call on already closed io!\n");
331 MSG_ERR(
"IO_submit: FD not initialized\n");
338 _MSG(
"IO_submit:: (%s) FD = %d\n",
339 (r_io->Op ==
IORead) ?
"IORead" :
"IOWrite", r_io->FD);
342 fcntl(r_io->FD, F_SETFL, O_NONBLOCK | fcntl(r_io->FD, F_GETFL));
343 fcntl(r_io->FD, F_SETFD, FD_CLOEXEC | fcntl(r_io->FD, F_GETFD));
349 }
else if (r_io->Op ==
IOWrite) {
360 void *Data1,
void *Data2)
378 if (Data2 && !strcmp(Data2,
"FD")) {
379 io->FD = *(
int*)Data1;
389 if (io->Buf->len > 0) {
390 char *newline = memchr(io->Buf->str,
'\n', io->Buf->len);
391 int msglen = newline ? newline - io->Buf->str : 2048;
393 MSG(
"IO_write, closing with pending data not sent: \"%s\"\n",
421 }
else if (Branch == 2) {
432 if (Data2 && !strcmp(Data2,
"FD")) {
433 io->FD = *(
int*)Data1;
static void IO_del(IOData_t *io)
Remove an IO from ValidIOs.
static void IO_submit(IOData_t *r_io)
Receive an IO request (IORead | IOWrite), Set a watch for it, and let it flow!
static IOData_t * IO_get(int Key)
Return a io by its Key (NULL if not found)
static bool_t IO_write(IOData_t *io)
Write data, from a specific buffer, into a file descriptor.
static void IO_fd_read_cb(int fd, void *data)
Handle the READ event of a FD.
void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the IO module.
static void IO_fd_write_cb(int fd, void *data)
Handle the WRITE event of a FD.
static void IO_close_fd(IOData_t *io, int CloseCode)
Close an open FD, and remove io controls.
static IOData_t * IO_new(int op)
Return a new, initialized, 'io' struct.
static bool_t IO_read(IOData_t *io)
Read data from a file descriptor into a specific buffer.
static Klist_t * ValidIOs
static void IO_ins(IOData_t *io)
Register an IO in ValidIOs.
static void IO_free(IOData_t *io)
Free an 'io' struct.
static int IO_callback(IOData_t *io)
Handle background IO for a given FD (reads | writes).
DataBuf * a_Chain_dbuf_new(void *buf, int size, int code)
Allocate and initialize a new DataBuf structure.
int a_Chain_check(char *FuncStr, int Op, int Branch, int Dir, ChainLink *Info)
Check whether the CCC is operative.
int a_Chain_fcb(int Op, ChainLink *Info, void *Data1, void *Data2)
Issue the forward callback of the 'Info' link.
Dstr * dStr_sized_new(int sz)
Create a new string with a given size.
void dStr_erase(Dstr *ds, int pos_0, int len)
Erase a substring.
void dStr_free(Dstr *ds, int all)
Free a dillo string.
int dClose(int fd)
Close a FD handling EINTR.
void dStr_append_l(Dstr *ds, const char *s, int l)
Append a C string to a Dstr (providing length).
const char * dStr_printable(Dstr *in, int maxlen)
Return a printable representation of the provided Dstr, limited to a length of roughly maxlen.
void dStr_truncate(Dstr *ds, int len)
Truncate a Dstr to be 'len' bytes long.
#define dReturn_if_fail(expr)
#define dNew0(type, count)
void a_IOwatch_add_fd(int fd, int when, Fl_FD_Handler Callback, void *usr_data=0)
Hook a Callback for a certain activities in a FD.
void a_IOwatch_remove_fd(int fd, int when)
Remove a Callback for a given FD (or just remove some events)
void a_Klist_remove(Klist_t *Klist, int Key)
Remove data by Key.
void * a_Klist_get_data(Klist_t *Klist, int Key)
Return the data pointer for a given Key (or NULL if not found)
int a_Klist_insert(Klist_t **Klist, void *Data)
Insert a data pointer and return a key for it.
int a_Klist_length(Klist_t *Klist)
Return the number of elements in the Klist.
Main data structure for CCC nodes.
A convenience data structure for passing data chunks between nodes.
int a_Tls_read(void *conn, void *buf, size_t len)
int a_Tls_write(void *conn, void *buf, size_t len)
void * a_Tls_connection(int fd)
Return TLS connection information for a given file descriptor, or NULL if no TLS connection was found...