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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user