[fpc-pascal] exceptions
Jonas Maebe
jonas.maebe at elis.ugent.be
Thu May 28 22:20:54 CEST 2009
On 28 May 2009, at 21:58, Rainer Stratmann wrote:
> Shrinked down example of the program.
strace shows this:
accept(3, {sa_family=AF_INET, sin_port=htons(48134),
sin_addr=inet_addr("xxx.xxx.xxx.xxx")}, [16]) = 4
write(1, ".", 1) = 1
select(0, NULL, NULL, NULL, {0, 300000}) = 0 (Timeout)
sendto(4, "\0", 1, 0, NULL, 0) = 1
write(1, "*", 1) = 1
select(0, NULL, NULL, NULL, {0, 300000}) = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0}) = 0 (Timeout)
sendto(4, "\0", 1, 0, NULL, 0) = 1
write(1, "*", 1) = 1
select(0, NULL, NULL, NULL, {0, 300000}) = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0}) = 0 (Timeout)
sendto(4, "\0", 1, 0, NULL, 0) = -1 ECONNRESET (Connection
reset by peer)
write(1, "*", 1) = 1
select(0, NULL, NULL, NULL, {0, 300000}) = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0}) = 0 (Timeout)
sendto(4, "\0", 1, 0, NULL, 0) = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
+++ killed by SIGPIPE +++
It's killed by SIGPIPE. SIGPIPE is signal number 13. This signal is
not caught by the RTL, and hence it's not translated into a Pascal
exception.
If you don't want SIGPIPE signals, use the MSG_NOSIGNAL flag (note
that this flag is not portable to all Unix-like systems). In that
case, fpsend() will return -1 and fpgeterrno will be set to ESysEPIPE
in case of a broken pipe. See "man send" for more information.
Note that you are using fpsend(), and not send() as you said earlier.
There is a big difference between these two routines. Also note that
you are using it wrongly, because you are not checking for ESysEINTR,
meaning that you can easily get data loss. You have to use something
like this:
repeat
l:=fpsend(handle,bufptr,bufpos,0);
until (l<>-1) or (fpgeterrno <> ESysEINTR);
You also have to make similar changes to your receiving side (in real
world programs), and to any other call to unix functions whose man
page states that they can return EINTR.
Jonas
More information about the fpc-pascal
mailing list