int mr_accept(int s, struct sockaddr_in *sin)
{
- int conn, addrlen = sizeof(struct sockaddr_in), nread, status;
- char *buf;
+ int conn = -1, addrlen = sizeof(struct sockaddr_in), nread, status;
+ char *buf = NULL;
- conn = accept(s, (struct sockaddr *)sin, &addrlen);
- if (conn < 0)
- return -1;
+ while (conn < 0)
+ {
+ conn = accept(s, (struct sockaddr *)sin, &addrlen);
+ if (conn < 0 && errno != EINTR)
+ return -1;
+ }
do
status = mr_cont_accept(conn, &buf, &nread);
return status;
}
+/* mr_cont_accept returns 0 if it has failed, an fd if it has succeeded,
+ or -1 if it is still making progress */
+
int mr_cont_accept(int conn, char **buf, int *nread)
{
long len, more;
if (read(conn, lbuf, 4) != 4)
{
close(conn);
- return -1;
+ return 0;
}
getlong(lbuf, len);
len += 4;
if (!*buf || len < 58)
{
close(conn);
- free(buf);
+ free(*buf);
return 0;
}
putlong(*buf, len);