From 7f8f4c9c8c1d951b3fa1ad1b7315cf900c6b5fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 28 Apr 2019 21:14:29 +0200 Subject: [PATCH] tty: some improvements to pass posix_openpt_test. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/add-ons/kernel/drivers/tty/master.cpp | 2 + src/add-ons/kernel/drivers/tty/tty.cpp | 35 ++++++++++------ src/add-ons/kernel/drivers/tty/tty_private.h | 1 + src/add-ons/kernel/generic/tty/tty.cpp | 42 +++++++++++++------- src/add-ons/kernel/generic/tty/tty_private.h | 1 + 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/add-ons/kernel/drivers/tty/master.cpp b/src/add-ons/kernel/drivers/tty/master.cpp index 476226de1e..8db1b11796 100644 --- a/src/add-ons/kernel/drivers/tty/master.cpp +++ b/src/add-ons/kernel/drivers/tty/master.cpp @@ -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 diff --git a/src/add-ons/kernel/drivers/tty/tty.cpp b/src/add-ons/kernel/drivers/tty/tty.cpp index 503b40c46e..95e53ed478 100644 --- a/src/add-ons/kernel/drivers/tty/tty.cpp +++ b/src/add-ons/kernel/drivers/tty/tty.cpp @@ -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; } diff --git a/src/add-ons/kernel/drivers/tty/tty_private.h b/src/add-ons/kernel/drivers/tty/tty_private.h index 8dc5d17f1f..a0c796fea3 100644 --- a/src/add-ons/kernel/drivers/tty/tty_private.h +++ b/src/add-ons/kernel/drivers/tty/tty_private.h @@ -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; diff --git a/src/add-ons/kernel/generic/tty/tty.cpp b/src/add-ons/kernel/generic/tty/tty.cpp index e1b9b2bcbb..8d09fa95c6 100644 --- a/src/add-ons/kernel/generic/tty/tty.cpp +++ b/src/add-ons/kernel/generic/tty/tty.cpp @@ -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; } diff --git a/src/add-ons/kernel/generic/tty/tty_private.h b/src/add-ons/kernel/generic/tty/tty_private.h index 97bbe68036..0da79e7078 100644 --- a/src/add-ons/kernel/generic/tty/tty_private.h +++ b/src/add-ons/kernel/generic/tty/tty_private.h @@ -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;