tty: some improvements to pass posix_openpt_test.

WriterLocker::AcquireWriter(): don't fail when the other end isn't yet opened.
WriterLocker::_CheckBackgroundWrite(): don't fail when the pgrp_id differs.
ReaderLocker::AcquireReader(): fail when the other end isn't opened anymore.
ReaderLocker::AcquireReader(): check available bytes even in case of failure.
ReaderLocker::_CheckBackgroundRead(): don't fail when the pgrp_id differs.

Change-Id: Ice2bd119cbec2afc9ebd40714e4307856f540ea2
Reviewed-on: https://review.haiku-os.org/c/1418
Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
Jérôme Duval
2019-05-29 17:02:56 +00:00
parent ec1d063cdd
commit 7f8f4c9c8c
5 changed files with 53 additions and 28 deletions
@@ -84,6 +84,8 @@ master_open(const char *name, uint32 flags, void **_cookie)
return B_BUSY;
}
gMasterTTYs[index].opened_count = 0;
gSlaveTTYs[index].opened_count = 0;
status_t status = tty_open(&gMasterTTYs[index], &master_service);
if (status < B_OK) {
// initializing TTY failed
+22 -13
View File
@@ -617,12 +617,8 @@ WriterLocker::AcquireWriter(bool dontBlock, size_t bytesNeeded)
if (status == B_OK)
status = _CheckBackgroundWrite();
if (status == B_OK) {
if (fTarget->open_count > 0)
fBytes = _CheckAvailableBytes();
else
status = B_FILE_ERROR;
}
if (status == B_OK)
fBytes = _CheckAvailableBytes();
return status;
}
@@ -642,7 +638,6 @@ WriterLocker::_CheckBackgroundWrite() const
&& processGroup != fSource->settings->pgrp_id) {
if (team_get_controlling_tty() == fSource->index)
send_signal(-processGroup, SIGTTOU);
return EIO;
}
return B_OK;
@@ -701,6 +696,13 @@ ReaderLocker::AcquireReader(bigtime_t timeout, size_t bytesNeeded)
return B_OK;
}
if (fCookie->other_tty->open_count == 0
&& fCookie->other_tty->opened_count > 0) {
TRACE(("ReaderLocker::AcquireReader() opened_count %" B_PRId32 "\n",
fCookie->other_tty->opened_count));
return B_FILE_ERROR;
}
// We are not the first in queue or currently there's nothing to read:
// bail out, if we shall not block.
if (timeout <= 0)
@@ -717,8 +719,10 @@ ReaderLocker::AcquireReader(bigtime_t timeout, size_t bytesNeeded)
if (status == B_OK)
status = _CheckBackgroundRead();
if (status == B_OK)
fBytes = _CheckAvailableBytes();
fBytes = _CheckAvailableBytes();
TRACE(("ReaderLocker::AcquireReader() ended status 0x%" B_PRIx32 "\n",
status));
return status;
}
@@ -751,7 +755,6 @@ ReaderLocker::_CheckBackgroundRead() const
&& processGroup != fTTY->settings->pgrp_id) {
if (team_get_controlling_tty() == fTTY->index)
send_signal(-processGroup, SIGTTIN);
return EIO;
}
return B_OK;
@@ -825,6 +828,7 @@ reset_tty(struct tty* tty, int32 index, mutex* lock, bool isMaster)
{
tty->ref_count = 0;
tty->open_count = 0;
tty->opened_count = 0;
tty->index = index;
tty->lock = lock;
tty->settings = &gTTYSettings[index];
@@ -998,6 +1002,7 @@ add_tty_cookie(tty_cookie* cookie)
// add to the TTY's cookie list
cookie->tty->cookies.Add(cookie);
cookie->tty->open_count++;
cookie->tty->opened_count++;
}
@@ -1872,10 +1877,12 @@ tty_input_read(tty_cookie* cookie, void* _buffer, size_t* _length)
TRACE(("tty_input_read: AcquireReader(%" B_PRIdBIGTIME "us, %ld)\n",
timeout, bytesNeeded));
status = locker.AcquireReader(timeout, bytesNeeded);
if (status != B_OK)
break;
size_t toRead = locker.AvailableBytes();
if (status != B_OK && toRead == 0) {
TRACE(("tty_input_read() AcquireReader failed\n"));
break;
}
if (toRead > length)
toRead = length;
@@ -1914,6 +1921,8 @@ tty_input_read(tty_cookie* cookie, void* _buffer, size_t* _length)
status = B_OK;
}
TRACE(("tty_input_read() status 0x%" B_PRIx32 "\n", status));
return *_length == 0 ? status : B_OK;
}
@@ -131,6 +131,7 @@ struct tty_settings {
struct tty {
int32 ref_count; // referenced by cookies
int32 open_count;
int32 opened_count;
int32 index;
struct mutex* lock;
tty_settings* settings;
+27 -15
View File
@@ -170,7 +170,7 @@ public:
if (semaphore >= 0) {
TRACE(("TTYReference: cookie %p closed, last operation done, "
"releasing blocking sem %ld\n", cookie, semaphore));
"releasing blocking sem %" B_PRId32 "\n", cookie, semaphore));
release_sem(semaphore);
}
@@ -419,8 +419,8 @@ RequestOwner::Wait(bool interruptable, bigtime_t timeout)
(interruptable ? B_CAN_INTERRUPT : 0) | B_RELATIVE_TIMEOUT,
timeout);
TRACE(("%p->RequestOwner::Wait(): condition occurred: %lx\n", this,
error));
TRACE(("%p->RequestOwner::Wait(): condition occurred: %" B_PRIx32 "\n",
this, error));
// remove the condition variable
locker.Lock();
@@ -474,7 +474,8 @@ RequestOwner::Notify(Request* request)
void
RequestOwner::NotifyError(Request* request, status_t error)
{
TRACE(("%p->RequestOwner::NotifyError(%p, %lx)\n", this, request, error));
TRACE(("%p->RequestOwner::NotifyError(%p, %" B_PRIx32 ")\n", this, request,
error));
if (fError == B_OK) {
fError = error;
@@ -602,12 +603,8 @@ WriterLocker::AcquireWriter(bool dontBlock, size_t bytesNeeded)
status = fRequestOwner.Error();
}
if (status == B_OK) {
if (fTarget->open_count > 0)
fBytes = _CheckAvailableBytes();
else
status = B_FILE_ERROR;
}
if (status == B_OK)
fBytes = _CheckAvailableBytes();
return status;
}
@@ -661,6 +658,13 @@ ReaderLocker::AcquireReader(bigtime_t timeout, size_t bytesNeeded)
return B_OK;
}
if (fCookie->other_tty->open_count == 0
&& fCookie->other_tty->opened_count > 0) {
TRACE(("ReaderLocker::AcquireReader() opened_count %" B_PRId32 "\n",
fCookie->other_tty->opened_count));
return B_FILE_ERROR;
}
// We are not the first in queue or currently there's nothing to read:
// bail out, if we shall not block.
if (timeout <= 0)
@@ -674,8 +678,10 @@ ReaderLocker::AcquireReader(bigtime_t timeout, size_t bytesNeeded)
status_t status = fRequestOwner.Wait(true, timeout);
Lock();
if (status == B_OK)
fBytes = _CheckAvailableBytes();
fBytes = _CheckAvailableBytes();
TRACE(("ReaderLocker::AcquireReader() ended status 0x%" B_PRIx32 "\n",
status));
return status;
}
@@ -1328,6 +1334,7 @@ tty_create(tty_service_func func, bool isMaster)
tty->ref_count = 0;
tty->open_count = 0;
tty->opened_count = 0;
tty->select_pool = NULL;
tty->is_master = isMaster;
tty->pending_eof = 0;
@@ -1391,6 +1398,7 @@ tty_create_cookie(struct tty* tty, struct tty* otherTTY, uint32 openMode)
tty->cookies.Add(cookie);
tty->open_count++;
tty->ref_count++;
tty->opened_count++;
return cookie;
}
@@ -1568,10 +1576,12 @@ tty_read(tty_cookie* cookie, void* _buffer, size_t* _length)
TRACE(("tty_input_read: AcquireReader(%Ldus, %ld)\n", timeout,
bytesNeeded));
status = locker.AcquireReader(timeout, bytesNeeded);
if (status != B_OK)
break;
size_t toRead = locker.AvailableBytes();
if (status != B_OK && toRead == 0) {
TRACE(("tty_input_read() AcquireReader failed\n"));
break;
}
if (toRead > length)
toRead = length;
@@ -1610,6 +1620,8 @@ tty_read(tty_cookie* cookie, void* _buffer, size_t* _length)
status = B_OK;
}
TRACE(("tty_input_read() status 0x%" B_PRIx32 "\n", status));
return *_length == 0 ? status : B_OK;
}
@@ -128,6 +128,7 @@ struct tty_settings {
struct tty {
int32 ref_count; // referenced by cookies
int32 open_count;
int32 opened_count;
struct mutex lock;
tty_settings settings;
select_sync_pool* select_pool;