You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Roy T. Fielding" <fi...@kiwi.ICS.UCI.EDU> on 1997/02/15 07:30:14 UTC
Re: [Fwd: [BUG]: "accept: I/O Error looping" on UnixWare]
I responded to a similar message on the newsgroup yesterday:
In <33...@direct.ca> "Derek C. Ferguson" <de...@direct.ca> writes:
> I don't think that's the problem... I've already dealt with the
>excessive open log files problem by opening only three logs and
>using custom logging. I've set the number of descriptors from
>256 to 1024, and I still get a consistent spam of these errors:
>
>[Tue Feb 11 22:58:22 1997] getsockname: Bad file number
>[Tue Feb 11 22:58:24 1997] accept: Protocol error
>[Tue Feb 11 22:58:24 1997] - socket error: accept failed
>[Tue Feb 11 22:58:24 1997] getsockname: Bad file number
>[Tue Feb 11 22:58:25 1997] read timed out for 153.35.17.62
>[Tue Feb 11 22:58:27 1997] accept: Protocol error
>[Tue Feb 11 22:58:27 1997] - socket error: accept failed
>[Tue Feb 11 22:58:27 1997] getsockname: Bad file number
>[Tue Feb 11 22:58:27 1997] accept: Protocol error
I think I know what the problem is, but it is a bit difficult to
describe without a patch and, due to an unfortunate coincidence,
I seem to be unable to do that today. Grump.
Anyway, if you look in http_main.c, in child_main(), you will find
===============
do {
clen = sizeof(sa_client);
csd = accept(sd, &sa_client, &clen);
} while (csd < 0 && errno == EINTR);
if (csd < 0)
log_unixerr("accept", NULL, "socket error: accept failed",
server_conf);
}
accept_mutex_off(); /* unlock after "accept" */
clen = sizeof(sa_server);
if(getsockname(csd, &sa_server, &clen) < 0) {
log_unixerr("getsockname", NULL, NULL, server_conf);
continue;
}
===============
The getsockname error is caused because the first if() above is
allowing the code to drop through even though csd < 0 (an invalid
file descriptor) instead of looping back to the select. A good fix
will involve more changes, but here is a quick (untested) fix:
===============
do {
clen = sizeof(sa_client);
csd = accept(sd, &sa_client, &clen);
} while (csd < 0 && errno == EINTR);
if (csd < 0) {
if ((errno != EPROTO) && (errno != ECONNABORTED))
log_unixerr("accept", NULL, "socket error: accept failed",
server_conf);
accept_mutex_off(); /* unlock after "accept" */
continue; /* while(1) */
}
}
accept_mutex_off(); /* unlock after "accept" */
clen = sizeof(sa_server);
if(getsockname(csd, &sa_server, &clen) < 0) {
log_unixerr("getsockname", NULL, NULL, server_conf);
continue;
}
===============
Note, however, that EPROTO and ECONNABORTED are not portable, so the
above will only work on SunOS5.5.1 without also adding #ifdefs.
In case you are wondering, those two errors mean that the client aborted
the connection between the select and the accept.
Like I said, the above is untested. Please let us know if it works.
...Roy T. Fielding
Department of Information & Computer Science (fielding@ics.uci.edu)
University of California, Irvine, CA 92697-3425 fax:+1(714)824-4056
http://www.ics.uci.edu/~fielding/