/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see .
*/
#include
#include
#include
#include
extern Driver::Manager *DriverManager;
namespace Driver::TeleTypeDevices
{
dev_t DriverID;
TTY::PTMXDevice *ptmx = nullptr;
struct
{
dev_t kcon;
dev_t tty;
dev_t ptmx;
} ids;
int Open(struct Inode *Node, int Flags, mode_t Mode)
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Term->Open(Flags, Mode);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
if (tty == nullptr)
return -ENOTTY;
return tty->Open(Flags, Mode);
}
else if (min == ids.ptmx)
return ptmx->Open();
return -ENODEV;
}
int Close(struct Inode *Node)
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Term->Close();
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
if (tty == nullptr)
return -ENOTTY;
return tty->Close();
}
else if (min == ids.ptmx)
return ptmx->Close();
return -ENODEV;
}
int Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Term->Ioctl(Request, Argp);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
if (tty == nullptr)
return -ENOTTY;
return tty->Ioctl(Request, Argp);
}
else if (min == ids.ptmx)
return -ENOSYS;
return -ENODEV;
}
ssize_t Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Term->Read(Buffer, Size, Offset);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
if (tty == nullptr)
return -ENOTTY;
return tty->Read(Buffer, Size, Offset);
}
else if (min == ids.ptmx)
return -ENOSYS;
return -ENODEV;
}
ssize_t Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
{
dev_t min = Node->GetMinor();
if (min == ids.kcon)
return KernelConsole::CurrentTerminal.load()->Term->Write(Buffer, Size, Offset);
else if (min == ids.tty)
{
TTY::TeletypeDriver *tty = (TTY::TeletypeDriver *)thisProcess->tty;
if (tty == nullptr)
return -ENOTTY;
return tty->Write(Buffer, Size, Offset);
}
else if (min == ids.ptmx)
return -ENOSYS;
return -ENODEV;
}
off_t Seek(struct Inode *Node, off_t Offset) { return -ENOSYS; }
int Stat(struct Inode *Node, struct kstat *Stat) { return -ENOSYS; }
const struct InodeOperations ops = {
.Lookup = nullptr,
.Create = nullptr,
.Remove = nullptr,
.Rename = nullptr,
.Read = Read,
.Write = Write,
.Truncate = nullptr,
.Open = Open,
.Close = Close,
.Ioctl = Ioctl,
.ReadDir = nullptr,
.MkDir = nullptr,
.RmDir = nullptr,
.SymLink = nullptr,
.ReadLink = nullptr,
.Seek = Seek,
.Stat = Stat,
};
int Entry()
{
ptmx = new TTY::PTMXDevice;
mode_t mode = 0;
/* c rw- r-- --- */
mode = S_IRUSR | S_IWUSR |
S_IRGRP |
S_IFCHR;
ids.kcon = DriverManager->CreateDeviceFile(DriverID, "console", mode, &ops);
/* c rw- rw- rw- */
mode = S_IRUSR | S_IWUSR |
S_IRGRP | S_IWGRP |
S_IRUSR | S_IWUSR |
S_IFCHR;
ids.tty = DriverManager->CreateDeviceFile(DriverID, "tty", mode, &ops);
ids.ptmx = DriverManager->CreateDeviceFile(DriverID, "ptmx", mode, &ops);
return 0;
}
int Final()
{
DriverManager->UnregisterDevice(DriverID, ids.kcon);
DriverManager->UnregisterDevice(DriverID, ids.tty);
DriverManager->UnregisterDevice(DriverID, ids.ptmx);
delete ptmx;
return 0;
}
int Panic() { return 0; }
int Probe() { return 0; }
REGISTER_BUILTIN_DRIVER(pty,
"Pseudo Terminal Devices Driver",
"enderice2",
1, 0, 0,
Entry,
Final,
Panic,
Probe);
}