1
0
mirror of https://github.com/UzixLS/picocom.git synced 2025-07-19 07:21:18 +03:00

Changed wrinetn_ni to work with non-blocking fds

Code in tn2217.c is using writen_ni() with the non-blocking socket
fd. This will not work. Instead of making the fd blocking (which is also
a solution), I made writen_ni work with both, blocking and non-blocking
fds.

Also added a time-out version of writen_ni(), called writento_ni() for
future use (we way want to protect writes with timeouts). Currently
commented out.
This commit is contained in:
Nick Patavalis
2018-02-27 17:26:29 +02:00
parent 96201b778c
commit faed52cd2e
2 changed files with 85 additions and 1 deletions

74
fdio.c
View File

@ -28,6 +28,9 @@
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
/**********************************************************************/
@ -37,6 +40,8 @@ writen_ni(int fd, const void *buff, size_t n)
size_t nl;
ssize_t nw;
const char *p;
fd_set wrset;
int r;
p = buff;
nl = n;
@ -44,7 +49,17 @@ writen_ni(int fd, const void *buff, size_t n)
do {
nw = write(fd, p, nl);
} while ( nw < 0 && errno == EINTR );
if ( nw <= 0 ) break;
if ( nw <= 0 ) {
if ( nw < 0 && (errno == EWOULDBLOCK || errno == EAGAIN) ) {
FD_ZERO(&wrset); FD_SET(fd, &wrset);
do {
r = select(fd + 1, 0, &wrset, 0, NULL);
} while ( r < 0 && errno == EINTR);
if ( r < 0 ) break;
continue;
}
break;
}
nl -= nw;
p += nw;
}
@ -52,6 +67,63 @@ writen_ni(int fd, const void *buff, size_t n)
return n - nl;
}
# if 0
ssize_t
writento_ni(int fd, const void *buff, size_t n,
int absolute, struct timeval *tv_tmo)
{
size_t nl;
ssize_t nw;
const char *p;
struct timeval tv_abs, now;
fd_set wrset;
int r;
if ( tv_tmo ) {
if ( ! absolute ) {
gettimeofday(&now, 0);
timeradd(&now, tv_tmo, &tv_abs);
} else tv_abs = *tv_tmo;
}
p = buff;
nl = n;
while (nl > 0) {
if ( tv_tmo ) {
gettimeofday(&now, 0);
if ( ! timercmp(&now, &tv_abs, <) ) {
errno = ETIMEDOUT;
break;
}
timersub(&tv_abs, &now, tv_tmo);
}
FD_ZERO(&wrset);
FD_SET(fd, &wrset);
do {
r = select(fd + 1, 0, &wrset, 0, tv_tmo);
} while ( r < 0 && errno == EINTR );
if ( r < 0 ) break;
if ( r == 0 ) { errno = ETIMEDOUT; break; }
do {
nw = write(fd, p, nl);
} while ( nw < 0 && errno == EINTR );
if ( nw <= 0 ) {
if ( r < 0 && (errno == EWOULDBLOCK || errno == EAGAIN) )
continue;
break;
}
nl -= nw;
p += nw;
}
return n - nl;
}
#endif
int
fd_vprintf (int fd, const char *format, va_list ap)
{

12
fdio.h
View File

@ -24,8 +24,20 @@
#ifndef FDIO_H
/* Write exactly "n" bytes from "buff" to "fd". Works with blocking
and non-blocking fds. Returns number of bytes written; if != "n",
sets errno. */
ssize_t writen_ni(int fd, const void *buff, size_t n);
#if 0
/* Write exactly "n" bytes from "buff" to "fd", with an optional
(relative or absolute) timeout "tv_tmo". Works with blocking and
non-blocking fds. Returns number of bytes written; if != "n", sets
errno. */
ssize_t writento_ni(int fd, const void *buff, size_t n,
int absolute, struct timeval *tv_tmo);
#endif
int fd_vprintf (int fd, const char *format, va_list ap);
int fd_printf (int fd, const char *format, ...);