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:
74
fdio.c
74
fdio.c
@ -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
12
fdio.h
@ -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, ...);
|
||||
|
Reference in New Issue
Block a user