summaryrefslogtreecommitdiff
path: root/gdb/rdi-share
diff options
context:
space:
mode:
authorJason Molenda <jsm@bugshack.cygnus.com>1999-11-02 04:44:47 +0000
committerJason Molenda <jsm@bugshack.cygnus.com>1999-11-02 04:44:47 +0000
commitca799f40e93972d04247a5bbc76b749a2d462824 (patch)
treed0142d7a9db3d791008037a060e4336032339c66 /gdb/rdi-share
parent1f80975aceb82ecd4fc9bf4e988e6d1b7c7bbca1 (diff)
downloadgdb-ca799f40e93972d04247a5bbc76b749a2d462824.tar.gz
import gdb-1999-11-01 snapshot
Diffstat (limited to 'gdb/rdi-share')
-rw-r--r--gdb/rdi-share/Makefile.am12
-rw-r--r--gdb/rdi-share/Makefile.in12
-rw-r--r--gdb/rdi-share/ardi.c10
-rw-r--r--gdb/rdi-share/devsw.c179
-rw-r--r--gdb/rdi-share/devsw.h11
-rw-r--r--gdb/rdi-share/etherdrv.c10
-rw-r--r--gdb/rdi-share/hostchan.c16
-rw-r--r--gdb/rdi-share/hostchan.h11
-rw-r--r--gdb/rdi-share/hsys.c6
-rw-r--r--gdb/rdi-share/msgbuild.c6
-rw-r--r--gdb/rdi-share/params.c6
-rw-r--r--gdb/rdi-share/rx.c6
-rw-r--r--gdb/rdi-share/tx.c6
-rw-r--r--gdb/rdi-share/unixcomm.c13
14 files changed, 257 insertions, 47 deletions
diff --git a/gdb/rdi-share/Makefile.am b/gdb/rdi-share/Makefile.am
index 9d63d1c6486..4dd71d89d0d 100644
--- a/gdb/rdi-share/Makefile.am
+++ b/gdb/rdi-share/Makefile.am
@@ -4,15 +4,15 @@ AUTOMAKE_OPTIONS = cygnus
noinst_LIBRARIES = libangsd.a
-libangsd_a_SOURCES = ardi.c bytesex.c crc.c devsw.c drivers.c etherdrv.c \
- hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \
- serdrv.c serpardr.c tx.c unixcomm.c
+libangsd_a_SOURCES = ardi.c angel_bytesex.c crc.c devsw.c drivers.c etherdrv.c \
+ hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \
+ serdrv.c serpardr.c tx.c unixcomm.c
-noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h bytesex.h \
+noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h \
chandefs.h channels.h chanpriv.h crc.h dbg_conf.h dbg_cp.h \
dbg_hif.h dbg_rdi.h devclnt.h devices.h devsw.h drivers.h \
- endian.h ethernet.h host.h hostchan.h hsys.h logging.h \
- msgbuild.h params.h rxtx.h sys.h unixcomm.h
+ angel_endian.h ethernet.h host.h hostchan.h hsys.h logging.h \
+ msgbuild.h params.h rxtx.h sys.h unixcomm.h angel_bytesex.h
EXTRA_DIST = README.CYGNUS
diff --git a/gdb/rdi-share/Makefile.in b/gdb/rdi-share/Makefile.in
index 33274dac7a7..a24e1afb9bb 100644
--- a/gdb/rdi-share/Makefile.in
+++ b/gdb/rdi-share/Makefile.in
@@ -70,15 +70,15 @@ AUTOMAKE_OPTIONS = cygnus
noinst_LIBRARIES = libangsd.a
-libangsd_a_SOURCES = ardi.c bytesex.c crc.c devsw.c drivers.c etherdrv.c \
- hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \
- serdrv.c serpardr.c tx.c unixcomm.c
+libangsd_a_SOURCES = ardi.c angel_bytesex.c crc.c devsw.c drivers.c etherdrv.c \
+ hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \
+ serdrv.c serpardr.c tx.c unixcomm.c
-noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h bytesex.h \
+noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h \
chandefs.h channels.h chanpriv.h crc.h dbg_conf.h dbg_cp.h \
dbg_hif.h dbg_rdi.h devclnt.h devices.h devsw.h drivers.h \
- endian.h ethernet.h host.h hostchan.h hsys.h logging.h \
- msgbuild.h params.h rxtx.h sys.h unixcomm.h
+ angel_endian.h ethernet.h host.h hostchan.h hsys.h logging.h \
+ msgbuild.h params.h rxtx.h sys.h unixcomm.h angel_bytesex.h
EXTRA_DIST = README.CYGNUS
diff --git a/gdb/rdi-share/ardi.c b/gdb/rdi-share/ardi.c
index 08de5e72058..f55d636450a 100644
--- a/gdb/rdi-share/ardi.c
+++ b/gdb/rdi-share/ardi.c
@@ -11,8 +11,8 @@
* Angel Remote Debug Interface
*
*
- * $Revision: 1.2 $
- * $Date: 1998/01/08 11:11:28 $
+ * $Revision: 1.5 $
+ * $Date: 1999/11/01 15:29:56 $
*
* This file is based on /plg/pisd/rdi.c, but instead of using RDP it uses
* ADP messages.
@@ -27,13 +27,13 @@
#undef uint
-#include "endian.h"
+#include "angel_endian.h"
#include "ardi.h"
#include "buffers.h"
#include "channels.h"
#include "hostchan.h"
#include "host.h"
-#include "bytesex.h"
+#include "angel_bytesex.h"
#include "dbg_cp.h"
#include "adp.h"
#include "hsys.h"
@@ -1300,7 +1300,7 @@ static int HandleStoppedMessage(Packet *packet, void *stateptr) {
stopped_info->stopped_status = RDIError_NoError;
break;
default:
- stopped_info->stopped_status = RDIError_NoError;
+ stopped_info->stopped_status = RDIError_Error;
break;
}
return RDIError_NoError;
diff --git a/gdb/rdi-share/devsw.c b/gdb/rdi-share/devsw.c
index 7bb15b4c04f..92b5969c64a 100644
--- a/gdb/rdi-share/devsw.c
+++ b/gdb/rdi-share/devsw.c
@@ -8,12 +8,13 @@
/* -*-C-*-
*
- * $Revision: 1.3 $
- * $Date: 1998/09/25 19:04:45 $
+ * $Revision: 1.4 $
+ * $Date: 1999/11/01 12:11:35 $
*
*/
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "adp.h"
#include "hsys.h"
@@ -26,6 +27,172 @@
#include "hostchan.h"
#include "logging.h"
+static char *angelDebugFilename = NULL;
+static FILE *angelDebugLogFile = NULL;
+static int angelDebugLogEnable = 0;
+
+static void openLogFile ()
+{
+ time_t t;
+ struct tm lt;
+
+ if (angelDebugFilename == NULL || *angelDebugFilename =='\0')
+ return;
+
+ angelDebugLogFile = fopen (angelDebugFilename,"a");
+
+ if (!angelDebugLogFile)
+ {
+ fprintf (stderr,"Error opening log file '%s'\n",angelDebugFilename);
+ perror ("fopen");
+ }
+ else
+ setlinebuf (angelDebugLogFile);
+
+ time (&t);
+ fprintf (angelDebugLogFile,"ADP log file opened at %s\n",asctime(localtime(&t)));
+}
+
+
+static void closeLogFile (void)
+{
+ time_t t;
+ struct tm lt;
+
+ if (!angelDebugLogFile)
+ return;
+
+ time (&t);
+ fprintf (angelDebugLogFile,"ADP log file closed at %s\n",asctime(localtime(&t)));
+
+ fclose (angelDebugLogFile);
+ angelDebugLogFile = NULL;
+}
+
+void DevSW_SetLogEnable (int logEnableFlag)
+{
+ if (logEnableFlag && !angelDebugLogFile)
+ openLogFile ();
+ else if (!logEnableFlag && angelDebugLogFile)
+ closeLogFile ();
+
+ angelDebugLogEnable = logEnableFlag;
+}
+
+
+void DevSW_SetLogfile (const char *filename)
+{
+ closeLogFile ();
+
+ if (angelDebugFilename)
+ {
+ free (angelDebugFilename);
+ angelDebugFilename = NULL;
+ }
+
+ if (filename && *filename)
+ {
+ angelDebugFilename = strdup (filename);
+ if (angelDebugLogEnable)
+ openLogFile ();
+ }
+}
+
+
+#define WordAt(p) ((unsigned long) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)))
+
+static void dumpPacket(FILE *fp, char *label, struct data_packet *p)
+{
+ unsigned r;
+ int i;
+
+ if (!fp)
+ return;
+
+ fprintf(fp,"%s [T=%d L=%d] ",label,p->type,p->len);
+ for (i=0; i<p->len; ++i)
+ fprintf(fp,"%02x ",p->data[i]);
+ fprintf(fp,"\n");
+
+ r = WordAt(p->data+4);
+
+ fprintf(fp,"R=%08x ",r);
+ fprintf(fp,"%s ", r&0x80000000 ? "H<-T" : "H->T");
+
+ switch ((r>>16) & 0xff)
+ {
+ case CI_PRIVATE: fprintf(fp,"CI_PRIVATE: "); break;
+ case CI_HADP: fprintf(fp,"CI_HADP: "); break;
+ case CI_TADP: fprintf(fp,"CI_TADP: "); break;
+ case CI_HBOOT: fprintf(fp,"CI_HBOOT: "); break;
+ case CI_TBOOT: fprintf(fp,"CI_TBOOT: "); break;
+ case CI_CLIB: fprintf(fp,"CI_CLIB: "); break;
+ case CI_HUDBG: fprintf(fp,"CI_HUDBG: "); break;
+ case CI_TUDBG: fprintf(fp,"CI_TUDBG: "); break;
+ case CI_HTDCC: fprintf(fp,"CI_HTDCC: "); break;
+ case CI_TTDCC: fprintf(fp,"CI_TTDCC: "); break;
+ case CI_TLOG: fprintf(fp,"CI_TLOG: "); break;
+ default: fprintf(fp,"BadChan: "); break;
+ }
+
+ switch (r & 0xffffff)
+ {
+ case ADP_Booted: fprintf(fp," ADP_Booted "); break;
+#if defined(ADP_TargetResetIndication)
+ case ADP_TargetResetIndication: fprintf(fp," ADP_TargetResetIndication "); break;
+#endif
+ case ADP_Reboot: fprintf(fp," ADP_Reboot "); break;
+ case ADP_Reset: fprintf(fp," ADP_Reset "); break;
+#if defined(ADP_HostResetIndication)
+ case ADP_HostResetIndication: fprintf(fp," ADP_HostResetIndication "); break;
+#endif
+ case ADP_ParamNegotiate: fprintf(fp," ADP_ParamNegotiate "); break;
+ case ADP_LinkCheck: fprintf(fp," ADP_LinkCheck "); break;
+ case ADP_HADPUnrecognised: fprintf(fp," ADP_HADPUnrecognised "); break;
+ case ADP_Info: fprintf(fp," ADP_Info "); break;
+ case ADP_Control: fprintf(fp," ADP_Control "); break;
+ case ADP_Read: fprintf(fp," ADP_Read "); break;
+ case ADP_Write: fprintf(fp," ADP_Write "); break;
+ case ADP_CPUread: fprintf(fp," ADP_CPUread "); break;
+ case ADP_CPUwrite: fprintf(fp," ADP_CPUwrite "); break;
+ case ADP_CPread: fprintf(fp," ADP_CPread "); break;
+ case ADP_CPwrite: fprintf(fp," ADP_CPwrite "); break;
+ case ADP_SetBreak: fprintf(fp," ADP_SetBreak "); break;
+ case ADP_ClearBreak: fprintf(fp," ADP_ClearBreak "); break;
+ case ADP_SetWatch: fprintf(fp," ADP_SetWatch "); break;
+ case ADP_ClearWatch: fprintf(fp," ADP_ClearWatch "); break;
+ case ADP_Execute: fprintf(fp," ADP_Execute "); break;
+ case ADP_Step: fprintf(fp," ADP_Step "); break;
+ case ADP_InterruptRequest: fprintf(fp," ADP_InterruptRequest "); break;
+ case ADP_HW_Emulation: fprintf(fp," ADP_HW_Emulation "); break;
+ case ADP_ICEbreakerHADP: fprintf(fp," ADP_ICEbreakerHADP "); break;
+ case ADP_ICEman: fprintf(fp," ADP_ICEman "); break;
+ case ADP_Profile: fprintf(fp," ADP_Profile "); break;
+ case ADP_InitialiseApplication: fprintf(fp," ADP_InitialiseApplication "); break;
+ case ADP_End: fprintf(fp," ADP_End "); break;
+ case ADP_TADPUnrecognised: fprintf(fp," ADP_TADPUnrecognised "); break;
+ case ADP_Stopped: fprintf(fp," ADP_Stopped "); break;
+ case ADP_TDCC_ToHost: fprintf(fp," ADP_TDCC_ToHost "); break;
+ case ADP_TDCC_FromHost: fprintf(fp," ADP_TDCC_FromHost "); break;
+ default: fprintf(fp," BadReason "); break;
+ }
+
+ i = 20;
+
+ if (((r & 0xffffff) == ADP_CPUread ||
+ (r & 0xffffff) == ADP_CPUwrite) && (r&0x80000000)==0)
+ {
+ fprintf(fp,"%02x ", p->data[i]);
+ ++i;
+ }
+
+ for (; i<p->len; i+=4)
+ fprintf(fp,"%08x ",WordAt(p->data+i));
+
+ fprintf(fp,"\n");
+}
+
+
/*
* TODO: this should be adjustable - it could be done by defining
* a reason code for DevSW_Ioctl. It could even be a
@@ -309,6 +476,10 @@ AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
#ifdef RET_DEBUG
printf("got a complete packet\n");
#endif
+
+ if (angelDebugLogEnable)
+ dumpPacket(angelDebugLogFile,"rx:",&ds->ds_activeread.dc_packet);
+
enqueue_packet(ds);
*packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
return adp_ok;
@@ -380,6 +551,10 @@ AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type)
* we can take this packet - set things up, then try to get rid of it
*/
initialise_write(dc, packet, type);
+
+ if (angelDebugLogEnable)
+ dumpPacket(angelDebugLogFile,"tx:",&dc->dc_packet);
+
flush_packet(device, dc);
return adp_ok;
diff --git a/gdb/rdi-share/devsw.h b/gdb/rdi-share/devsw.h
index 43a4193d4b0..0a255f96f5f 100644
--- a/gdb/rdi-share/devsw.h
+++ b/gdb/rdi-share/devsw.h
@@ -8,8 +8,8 @@
/* -*-C-*-
*
- * $Revision: 1.2 $
- * $Date: 1998/01/08 11:12:00 $
+ * $Revision: 1.3 $
+ * $Date: 1999/11/01 12:11:37 $
*
*/
#ifndef angsd_devsw_h
@@ -259,6 +259,13 @@ AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args);
*/
bool DevSW_WriteFinished(const DeviceDescr *device);
+
+/*
+ * set filename and enable/disable logginf of ADP packets
+ */
+void DevSW_SetLogfile(const char *filename);
+void DevSW_SetLogEnable(int logEnableFlag);
+
#ifdef __cplusplus
}
#endif
diff --git a/gdb/rdi-share/etherdrv.c b/gdb/rdi-share/etherdrv.c
index c56edf3c8c3..72e44fdc545 100644
--- a/gdb/rdi-share/etherdrv.c
+++ b/gdb/rdi-share/etherdrv.c
@@ -8,8 +8,8 @@
/* -*-C-*-
*
- * $Revision: 1.6 $
- * $Date: 1998/04/16 20:14:51 $
+ * $Revision: 1.8 $
+ * $Date: 1999/11/01 15:32:58 $
*
*
* etherdrv.c - Ethernet Driver for Angel.
@@ -71,7 +71,7 @@
#include "hsys.h"
#include "devices.h"
-#include "endian.h"
+#include "angel_endian.h"
#include "buffers.h"
#include "hostchan.h"
#include "params.h"
@@ -282,6 +282,10 @@ static void fetch_ports(void)
* port on the remote target
*/
ia->sin_port = htons(CTRL_PORT);
+#ifdef DEBUG
+ printf("CTLR_PORT=0x%04x sin_port=0x%04x\n");
+#endif
+
if (sendto(sock, ctrlpacket, sizeof(ctrlpacket), 0,
(struct sockaddr *)ia, sizeof(*ia)) < 0)
{
diff --git a/gdb/rdi-share/hostchan.c b/gdb/rdi-share/hostchan.c
index e4da694f467..7d293ca1da9 100644
--- a/gdb/rdi-share/hostchan.c
+++ b/gdb/rdi-share/hostchan.c
@@ -8,8 +8,8 @@
/* -*-C-*-
*
- * $Revision: 1.6 $
- * $Date: 1999/01/28 03:50:15 $
+ * $Revision: 1.8 $
+ * $Date: 1999/11/01 15:32:59 $
*
*
* hostchan.c - Semi Synchronous Host side channel interface for Angel.
@@ -230,7 +230,7 @@ void Adp_addToQueue(Packet **head, Packet *newpkt)
*/
ASSERT(&(((Packet *)0)->pk_next) == 0, "bad struct Packet layout");
-#if DEBUG && 0
+#if defined(DEBUG) && 0
printf("Adp_addToQueue(%p, %p)\n", head, newpkt);
#endif
@@ -265,6 +265,16 @@ Packet *Adp_removeFromQueue(Packet **head)
return pk;
}
+void Adp_SetLogEnable(int logEnableFlag)
+{
+ DevSW_SetLogEnable(logEnableFlag);
+}
+
+void Adp_SetLogfile(const char *filename)
+{
+ DevSW_SetLogfile(filename);
+}
+
AdpErrs Adp_OpenDevice(const char *name, const char *arg,
unsigned int heartbeat_on)
{
diff --git a/gdb/rdi-share/hostchan.h b/gdb/rdi-share/hostchan.h
index 49cc5b8d01f..b7a1cab550d 100644
--- a/gdb/rdi-share/hostchan.h
+++ b/gdb/rdi-share/hostchan.h
@@ -8,8 +8,8 @@
/* -*-C-*-
*
- * $Revision: 1.5 $
- * $Date: 1999/01/28 03:50:16 $
+ * $Revision: 1.6 $
+ * $Date: 1999/11/01 12:11:39 $
*
*/
#ifndef angsd_hostchan_h
@@ -92,6 +92,13 @@ extern void Adp_addToQueue(Packet **head, Packet *newpkt);
extern Packet *Adp_removeFromQueue(Packet **head);
/*
+ * Set log file and Enable/disable logging of ADP packets to file.
+ */
+
+void Adp_SetLogfile(const char *filename);
+void Adp_SetLogEnable(int logEnableFlag);
+
+/*
* Function: Adp_OpenDevice
* Purpose: Open a device to use for channels communication. This is a
* very thin veneer to the device drivers: what hostchan.c
diff --git a/gdb/rdi-share/hsys.c b/gdb/rdi-share/hsys.c
index 32f483adb21..ef9cdeb6f50 100644
--- a/gdb/rdi-share/hsys.c
+++ b/gdb/rdi-share/hsys.c
@@ -9,8 +9,8 @@
/*
* Host C Library support functions.
*
- * $Revision: 1.2 $
- * $Date: 1998/01/08 11:12:14 $
+ * $Revision: 1.3 $
+ * $Date: 1999/11/01 13:31:36 $
*/
#ifdef DEBUG
@@ -29,7 +29,7 @@
#include "ardi.h"
#include "buffers.h"
#include "channels.h" /* Channel interface. */
-#include "endian.h"
+#include "angel_endian.h"
#include "logging.h" /* Angel support functions. */
#include "msgbuild.h"
#include "sys.h"
diff --git a/gdb/rdi-share/msgbuild.c b/gdb/rdi-share/msgbuild.c
index bf385d3966c..5c6b2242355 100644
--- a/gdb/rdi-share/msgbuild.c
+++ b/gdb/rdi-share/msgbuild.c
@@ -8,8 +8,8 @@
/* -*-C-*-
*
- * $Revision: 1.2 $
- * $Date: 1998/01/08 11:12:21 $
+ * $Revision: 1.3 $
+ * $Date: 1999/11/01 13:31:38 $
*
*
* msgbuild.c - utilities for assembling and interpreting ADP messages
@@ -28,7 +28,7 @@
#include "channels.h"
#include "buffers.h"
-#include "endian.h" /* Endianness support macros */
+#include "angel_endian.h" /* Endianness support macros */
#include "msgbuild.h" /* Header file for this source code */
#ifndef UNUSED
diff --git a/gdb/rdi-share/params.c b/gdb/rdi-share/params.c
index 2fb10bb26f4..436b4dd0d19 100644
--- a/gdb/rdi-share/params.c
+++ b/gdb/rdi-share/params.c
@@ -8,8 +8,8 @@
/* -*-C-*-
*
- * $Revision: 1.2 $
- * $Date: 1998/01/08 11:12:24 $
+ * $Revision: 1.3 $
+ * $Date: 1999/11/01 13:31:39 $
*
*
* Project: ANGEL
@@ -19,7 +19,7 @@
#include "params.h"
-#include "endian.h"
+#include "angel_endian.h"
#include "logging.h"
diff --git a/gdb/rdi-share/rx.c b/gdb/rdi-share/rx.c
index 306b4a199d8..981e0c9ee21 100644
--- a/gdb/rdi-share/rx.c
+++ b/gdb/rdi-share/rx.c
@@ -8,8 +8,8 @@
/*-*-C-*-
*
- * $Revision: 1.2 $
- * $Date: 1998/01/08 11:12:27 $
+ * $Revision: 1.3 $
+ * $Date: 1999/11/01 13:31:40 $
*
*
* Project: ANGEL
@@ -19,7 +19,7 @@
#include <stdarg.h> /* ANSI varargs support */
#include "angel.h" /* Angel system definitions */
-#include "endian.h" /* Endian independant memory access macros */
+#include "angel_endian.h" /* Endian independant memory access macros */
#include "crc.h" /* crc generation definitions and headers */
#include "rxtx.h"
#include "channels.h"
diff --git a/gdb/rdi-share/tx.c b/gdb/rdi-share/tx.c
index d96cf60dea1..b7fbaac6cd0 100644
--- a/gdb/rdi-share/tx.c
+++ b/gdb/rdi-share/tx.c
@@ -8,8 +8,8 @@
/*-*-C-*-
*
- * $Revision: 1.2 $
- * $Date: 1998/01/08 11:12:36 $
+ * $Revision: 1.3 $
+ * $Date: 1999/11/01 13:31:43 $
*
* Project: ANGEL
*
@@ -18,7 +18,7 @@
#include <stdarg.h> /* ANSI varargs support */
#include "angel.h" /* Angel system definitions */
-#include "endian.h" /* Endian independant memory access macros */
+#include "angel_endian.h" /* Endian independant memory access macros */
#include "crc.h" /* crc generation definitions and headers */
#include "rxtx.h"
#include "channels.h"
diff --git a/gdb/rdi-share/unixcomm.c b/gdb/rdi-share/unixcomm.c
index fbcfe1b81e1..cbca5e3cdd4 100644
--- a/gdb/rdi-share/unixcomm.c
+++ b/gdb/rdi-share/unixcomm.c
@@ -8,8 +8,8 @@
/* -*-C-*-
*
- * $Revision: 1.7 $
- * $Date: 1999/07/15 14:38:39 $
+ * $Revision: 1.8 $
+ * $Date: 1999/11/01 15:33:00 $
*
*/
@@ -287,7 +287,14 @@ extern int Unix_ReadSerial(unsigned char *buf, int n, bool block)
return -1;
}
else if (err > 0 && FD_ISSET(serpfd, &fdset))
- return read(serpfd, buf, n);
+ {
+ int s;
+
+ s = read(serpfd, buf, n);
+ if (s < 0)
+ perror("read:");
+ return s;
+ }
else /* err == 0 || FD_CLR(serpfd, &fdset) */
{
errno = ERRNO_FOR_BLOCKED_IO;