/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include namespace Kernel { static Singleton s_the; PTYMultiplexer& PTYMultiplexer::the() { return *s_the; } UNMAP_AFTER_INIT PTYMultiplexer::PTYMultiplexer() : CharacterDevice(5, 2) { m_freelist.with_exclusive([&](auto& freelist) { freelist.ensure_capacity(max_pty_pairs); for (int i = max_pty_pairs; i > 0; --i) freelist.unchecked_append(i - 1); }); } UNMAP_AFTER_INIT PTYMultiplexer::~PTYMultiplexer() { } void PTYMultiplexer::initialize() { the().after_inserting(); } ErrorOr> PTYMultiplexer::open(int options) { return m_freelist.with_exclusive([&](auto& freelist) -> ErrorOr> { if (freelist.is_empty()) return EBUSY; auto master_index = freelist.take_last(); auto master = TRY(MasterPTY::try_create(master_index)); dbgln_if(PTMX_DEBUG, "PTYMultiplexer::open: Vending master {}", master->index()); auto description = TRY(OpenFileDescription::try_create(*master)); description->set_rw_mode(options); description->set_file_flags(options); return description; }); } void PTYMultiplexer::notify_master_destroyed(Badge, unsigned index) { m_freelist.with_exclusive([&](auto& freelist) { freelist.append(index); dbgln_if(PTMX_DEBUG, "PTYMultiplexer: {} added to freelist", index); }); } }