Serenity Operating System
at master 65 lines 1.8 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Singleton.h> 8#include <Kernel/API/POSIX/errno.h> 9#include <Kernel/Debug.h> 10#include <Kernel/FileSystem/OpenFileDescription.h> 11#include <Kernel/Sections.h> 12#include <Kernel/TTY/MasterPTY.h> 13#include <Kernel/TTY/PTYMultiplexer.h> 14 15namespace Kernel { 16 17static Singleton<PTYMultiplexer> s_the; 18 19PTYMultiplexer& PTYMultiplexer::the() 20{ 21 return *s_the; 22} 23 24UNMAP_AFTER_INIT PTYMultiplexer::PTYMultiplexer() 25 : CharacterDevice(5, 2) 26{ 27 m_freelist.with([&](auto& freelist) { 28 freelist.ensure_capacity(max_pty_pairs); 29 for (int i = max_pty_pairs; i > 0; --i) 30 freelist.unchecked_append(i - 1); 31 }); 32} 33 34UNMAP_AFTER_INIT PTYMultiplexer::~PTYMultiplexer() = default; 35 36UNMAP_AFTER_INIT void PTYMultiplexer::initialize() 37{ 38 MUST(the().after_inserting()); 39} 40 41ErrorOr<NonnullRefPtr<OpenFileDescription>> PTYMultiplexer::open(int options) 42{ 43 return m_freelist.with([&](auto& freelist) -> ErrorOr<NonnullRefPtr<OpenFileDescription>> { 44 if (freelist.is_empty()) 45 return EBUSY; 46 47 auto master_index = freelist.take_last(); 48 auto master = TRY(MasterPTY::try_create(master_index)); 49 dbgln_if(PTMX_DEBUG, "PTYMultiplexer::open: Vending master {}", master->index()); 50 auto description = TRY(OpenFileDescription::try_create(*master)); 51 description->set_rw_mode(options); 52 description->set_file_flags(options); 53 return description; 54 }); 55} 56 57void PTYMultiplexer::notify_master_destroyed(Badge<MasterPTY>, unsigned index) 58{ 59 m_freelist.with([&](auto& freelist) { 60 freelist.append(index); 61 dbgln_if(PTMX_DEBUG, "PTYMultiplexer: {} added to freelist", index); 62 }); 63} 64 65}