TCP, UNIX sockets: allow multiple calls to listen

* Subsequent calls to listen on an already-listening socket can resize
  the backlog.
* While not explicitly spelled out by POSIX, this behaviour is
  consistent with FreeBSD and Linux.
This commit is contained in:
Hamish Morrison 2015-01-17 17:27:04 +00:00
parent ba483af7de
commit 64f6fcbccd
2 changed files with 27 additions and 22 deletions

View File

@ -728,18 +728,20 @@ TCPEndpoint::Listen(int count)
MutexLocker _(fLock);
if (fState != CLOSED)
if (fState != CLOSED && fState != LISTEN)
return B_BAD_VALUE;
fAcceptSemaphore = create_sem(0, "tcp accept");
if (fAcceptSemaphore < B_OK)
return ENOBUFS;
status_t status = fManager->SetPassive(this);
if (status != B_OK) {
delete_sem(fAcceptSemaphore);
fAcceptSemaphore = -1;
return status;
if (fState == CLOSED) {
fAcceptSemaphore = create_sem(0, "tcp accept");
if (fAcceptSemaphore < B_OK)
return ENOBUFS;
status_t status = fManager->SetPassive(this);
if (status != B_OK) {
delete_sem(fAcceptSemaphore);
fAcceptSemaphore = -1;
return status;
}
}
gSocketModule->set_max_backlog(socket, count);

View File

@ -239,22 +239,25 @@ UnixEndpoint::Listen(int backlog)
if (!IsBound())
RETURN_ERROR(EDESTADDRREQ);
if (fState != UNIX_ENDPOINT_NOT_CONNECTED)
if (fState != UNIX_ENDPOINT_NOT_CONNECTED
&& fState != UNIX_ENDPOINT_LISTENING)
RETURN_ERROR(EINVAL);
gSocketModule->set_max_backlog(socket, backlog);
fAcceptSemaphore = create_sem(0, "unix accept");
if (fAcceptSemaphore < 0)
RETURN_ERROR(ENOBUFS);
_UnsetReceiveFifo();
fCredentials.pid = getpid();
fCredentials.uid = geteuid();
fCredentials.gid = getegid();
fState = UNIX_ENDPOINT_LISTENING;
if (fState == UNIX_ENDPOINT_NOT_CONNECTED) {
fAcceptSemaphore = create_sem(0, "unix accept");
if (fAcceptSemaphore < 0)
RETURN_ERROR(ENOBUFS);
_UnsetReceiveFifo();
fCredentials.pid = getpid();
fCredentials.uid = geteuid();
fCredentials.gid = getegid();
fState = UNIX_ENDPOINT_LISTENING;
}
RETURN_ERROR(B_OK);
}