On 19 Nov, 13:11, arnuld <sunr...@invalid.addresswrote:
Can anyone point me to some online/offline document on error handling in C?
I've never seen a good one. Doesn't mean there isn't one, just I've
never seen it.
I am doing some Socket Programming in C and feeling a lots of difficult in
error handling :(
yeah, error handling in C can be a pain. Especially if you've used
something with exceptions.
You might end up with something like this:-
<code>
int activesock (const char *host, int port, const char *protocol)
{
struct hostent *phe;
struct servent *pse;
struct protoent *ppe;
struct sockaddr_in sin;
int s, type;
memset (&sin, 0, sizeof sin);
sin.sin_family =AF_INET;
sin.sin_port = htons (port);
/* map host name to ip addr allowing for dotted decimal */
if ((phe = gethostbyname (host)))
memcpy (&sin.sin_addr, phe->h_addr, phe->h_length);
else
if ((sin.sin_addr.s_addr = inet_addr (host)) == INADDR_NONE)
raise_report (LEVEL_FATAL, "activesock", "can't get \"%s\"
host entry\n", host);
/* map protocol name to protocol number */
if ((ppe = getprotobyname (protocol)) == 0)
raise_report (LEVEL_FATAL, "activesock", "can't get \"%s\"
protocol entry\n", protocol);
/* use protoicol to choose socket type */
if (strcmp (protocol, "udp") == 0)
type = SOCK_DGRAM;
else
type = SOCK_STREAM;
/* allocate a socket */
/* s = socket (PF_INET, type, ppe->p_proto); */
s = socket (PF_INET, type, DEFAULT_PROTOCOL);
if (s < 0)
raise_report (LEVEL_FATAL, "activesock", "can't create socket:
%s\n", strerror (errno));
/* connect to the socket */
if (connect (s, (struct sockaddr *)&sin, sizeof sin) < 0)
raise_report (LEVEL_FATAL, "activesock", "can't connect to %s.
%d: %s\n", host, port, strerror (errno));
return s;
}
</code>
basically you have to check the return value of every function.
But then that's good for you. Much as eating your vegetables and
drinking 2 pts of water is good for you.
In the above raise_report() writes to a log file and possibly
terminates the program.
A language with exceptions can look much nicer
<code>
DEFAULT_PROTOCOL = 0
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM,
DEFAULT_PROTOCOL)
if len (sys.argv) < 2 :
host = "localhost"
else:
host = sys.argv [1]
sock.connect ((host, 8702))
</code>
But, of course, exceptions have their own pitfalls.
Also some time ago some one told me that when I get an error then I can
create a generic function which, when called within some function will
print the name of that function automatically or something like that I
forgot. It had lots of #define(s) . Can someone write that for me ?
I don't think you can do this in C89. C99 has something like
__function__()
(I can't rememeber the exact spelling). My report routine above
takes a parameter for the function name. To be honest __FILE__ and
__LINE__ are usually good enough for me. Ok you don't want the user
to
see file and line, but then you don't want him to see function either.
One trick is to have your functions return an error value.
Rv do_big_thing()
{
do_sub_thing1();
do_sub_thing_2();
return OK;
}
this can be nested
Rv do_big_thing()
{
if ((rv = do_sub_thing1()) != OK)
{
log_error();
return rv;
}
if ((rv = do_sub_thing_2()) != OK)
{
log_error();
return rv;
}
return OK;
}
with suitable macro trickery this reduces to
Rv do_big_thing()
{
CHECK_CALL (do_sub_thing1());
CHECK_CALL (do_sub_thing_2());
return OK;
}
of course I now have a nasty macro, a global variable and a function
with multiple exits.
The price of greenspunning
--
Nick Keighley
why isn't there an obfuscated C++ contest?