summaryrefslogtreecommitdiffstats
path: root/ax25ipd
diff options
context:
space:
mode:
authorThomas Osterried <thomas@osterried.de>2006-06-10 12:26:30 +0000
committerThomas Osterried <thomas@osterried.de>2006-06-10 12:26:30 +0000
commit170a4dc237341262e0c1b2578862d4d58e8a985a (patch)
treea75edeed5153b1830f082d4a4845db6519fb4b36 /ax25ipd
parenta0cb4e4e7642bd4b1a7a63d11522a2933b543cea (diff)
io.c: io_error(): patch from testing upstream version.
fixes problem that it tends to terminate even if it need not to
Diffstat (limited to 'ax25ipd')
-rw-r--r--ax25ipd/ax25ipd.h2
-rw-r--r--ax25ipd/io.c56
2 files changed, 41 insertions, 17 deletions
diff --git a/ax25ipd/ax25ipd.h b/ax25ipd/ax25ipd.h
index 818cd50..fac25fc 100644
--- a/ax25ipd/ax25ipd.h
+++ b/ax25ipd/ax25ipd.h
@@ -163,7 +163,7 @@ void io_open(void);
void io_start(void);
void send_ip(unsigned char *, int, unsigned char *);
void send_tty(unsigned char *, int);
-int io_error(int, unsigned char *, int, int, int);
+int io_error(int, unsigned char *, int, int, int, int);
/* crc.c */
unsigned short int compute_crc(unsigned char *, int);
diff --git a/ax25ipd/io.c b/ax25ipd/io.c
index 17375e2..2eeb0ea 100644
--- a/ax25ipd/io.c
+++ b/ax25ipd/io.c
@@ -360,7 +360,7 @@ void io_start() {
do {
n = read(ttyfd, buf, MAX_FRAME);
}
- while (io_error(n, buf, n, READ_MSG, TTY_MODE));
+ while (io_error(n, buf, n, READ_MSG, TTY_MODE, __LINE__));
LOGL4("ttydata l=%d\n", n);
if (n > 0) {
if (!ttyfd_bpq) {
@@ -388,7 +388,7 @@ out_ttyfd:
fromlen = sizeof from;
n = recvfrom(udpsock, buf, MAX_FRAME, 0, (struct sockaddr *) &from, &fromlen);
}
- while (io_error(n, buf, n, READ_MSG, UDP_MODE));
+ while (io_error(n, buf, n, READ_MSG, UDP_MODE, __LINE__));
LOGL4("udpdata from=%s port=%d l=%d\n", (char *) inet_ntoa(from. sin_addr), ntohs(from. sin_port), n);
stats.udp_in++;
if (n > 0)
@@ -402,7 +402,7 @@ out_ttyfd:
fromlen = sizeof from;
n = recvfrom(sock, buf, MAX_FRAME, 0, (struct sockaddr *) &from, &fromlen);
}
- while (io_error(n, buf, n, READ_MSG, IP_MODE));
+ while (io_error(n, buf, n, READ_MSG, IP_MODE, __LINE__));
ipptr = (struct iphdr *) buf;
hdr_len = 4 * ipptr-> ihl;
LOGL4("ipdata from=%s l=%d, hl=%d\n", (char *) inet_ntoa(from. sin_addr), n, hdr_len);
@@ -416,7 +416,7 @@ out_ttyfd:
fromlen = sizeof from;
n = recvfrom(icmpsock, buf, MAX_FRAME, 0, (struct sockaddr *) &from, &fromlen);
}
- while (io_error(n, buf, n, READ_MSG, ICMP_MODE));
+ while (io_error(n, buf, n, READ_MSG, ICMP_MODE, __LINE__));
ipptr = (struct iphdr *) buf;
hdr_len = 4 * ipptr-> ihl;
LOGL4("icmpdata from=%s l=%d, hl=%d\n", (char *) inet_ntoa(from. sin_addr), n, hdr_len);
@@ -449,7 +449,7 @@ unsigned char *targetip;
do {
n = sendto(udpsock, buf, l, 0, (struct sockaddr *) &to, sizeof to);
}
- while (io_error(n, buf, l, SEND_MSG, UDP_MODE));
+ while (io_error(n, buf, l, SEND_MSG, UDP_MODE, __LINE__));
}
} else {
if (ip_mode) {
@@ -457,7 +457,7 @@ unsigned char *targetip;
do {
n = sendto(sock, buf, l, 0, (struct sockaddr *) &to, sizeof to);
}
- while (io_error(n, buf, l, SEND_MSG, IP_MODE));
+ while (io_error(n, buf, l, SEND_MSG, IP_MODE, __LINE__));
}
}
}
@@ -505,28 +505,52 @@ int l;
}
}
}
- while (((n > 0) && (n < nc)) || (io_error(n, p, nc, SEND_MSG, TTY_MODE)));
+ while (((n > 0) && (n < nc)) || (io_error(n, p, nc, SEND_MSG, TTY_MODE, __LINE__)));
}
/* process an I/O error; return true if a retry is needed */
-int io_error(oops, buf, bufsize, dir, mode)
+int io_error(oops, buf, bufsize, dir, mode, where)
int oops; /* the error flag; < 0 indicates a problem */
unsigned char *buf; /* the data in question */
int bufsize; /* the size of the data buffer */
int dir; /* the direction; input or output */
int mode; /* the fd on which we got the error */
+int where; /* line in the code where this function was called */
{
- if (oops >= 0)
- return 0; /* do we have an error ? */
+ /* if (oops >= 0)
+ return 0; */ /* do we have an error ? */
+ /* dl9sau: nobody has set fd's to O_NONBLOCK.
+ * thus EAGAIN (below) or EWOULDBLOCK are never be set.
+ * Has someone removed this behaviour previously?
+ * Anyway, in the current implementation, with blocking
+ * read/writes, a read or write of 0 bytes means EOF,
+ * for e.g. if the attached tty is closed.
+ * We have to exit then. We've currentlsy no mechanism
+ * for regulary reconnects.
+ */
+ if (oops > 0)
+ return 0; /* do we have an error ? */
+
+ if (oops == 0) {
+ if (dir == READ_MSG && oops != TTY_MODE /* && != TCP_MODE, if we'd implement this */ )
+ return 0;
+ fprintf(stderr, "Close event on mode 0x%2.2x (during %s). LINE %d. Terminating normaly.\n", mode, (dir == READ_MSG ? "READ" : "WRITE"), where);
+ exit(1);
+ }
#ifdef EAGAIN
- if (errno == EAGAIN) {
- perror("System 5 I/O error!");
- fprintf(stderr, "A System 5 style I/O error was detected. This program requires BSD 4.2\n");
- fprintf(stderr, "behaviour. This is probably a result of compile-time environment.\n");
- exit(3);
- }
+ if (errno == EAGAIN) {
+ /* select() said that data is available, but recvfrom sais
+ * EAGAIN - i really do not know what's the sense in this.. */
+ if (dir == READ_MSG && oops != TTY_MODE /* && != TCP_MODE, if we'd implement this */ )
+ return 0;
+ perror("System 5 I/O error!");
+ fprintf(stderr, "A System 5 style I/O error was detected. This rogram requires BSD 4.2\n");
+ fprintf(stderr, "behaviour. This is probably a result of compile-time environment.\n");
+ fprintf(stderr, "Mode 0x%2.2x, LINE: %d. During %s\n", mode, where, (dir == READ_MSG ? "READ" : "WRITE"));
+ exit(3);
+ }
#endif
if (dir == READ_MSG) {