mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 01:12:44 +00:00 
			
		
		
		
	Add sys$ttyname_r and ttyname_r() + ttyname().
And print a greeting when sh starts up so we know which TTY we're on.
This commit is contained in:
		
							parent
							
								
									7a85384e47
								
							
						
					
					
						commit
						00c21d1590
					
				
					 12 changed files with 78 additions and 3 deletions
				
			
		|  | @ -114,6 +114,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) | ||||||
|         return current->sys$set_mmap_name((void*)arg1, (size_t)arg2, (const char*)arg3); |         return current->sys$set_mmap_name((void*)arg1, (size_t)arg2, (const char*)arg3); | ||||||
|     case Syscall::PosixReadlink: |     case Syscall::PosixReadlink: | ||||||
|         return current->sys$readlink((const char*)arg1, (char*)arg2, (size_t)arg3); |         return current->sys$readlink((const char*)arg1, (char*)arg2, (size_t)arg3); | ||||||
|  |     case Syscall::PosixTtynameR: | ||||||
|  |         return current->sys$ttyname_r((int)arg1, (char*)arg2, (size_t)arg3); | ||||||
|     default: |     default: | ||||||
|         kprintf("int0x80: Unknown function %x requested {%x, %x, %x}\n", function, arg1, arg2, arg3); |         kprintf("int0x80: Unknown function %x requested {%x, %x, %x}\n", function, arg1, arg2, arg3); | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ enum Function { | ||||||
|     SetMmapName = 0x2005, |     SetMmapName = 0x2005, | ||||||
|     PosixReadlink = 0x2006, |     PosixReadlink = 0x2006, | ||||||
|     PosixWrite = 0x2007, |     PosixWrite = 0x2007, | ||||||
|  |     PosixTtynameR = 0x2008, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void initialize(); | void initialize(); | ||||||
|  |  | ||||||
|  | @ -13,6 +13,8 @@ public: | ||||||
|     virtual String ttyName() const = 0; |     virtual String ttyName() const = 0; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |     virtual bool isTTY() const final { return true; } | ||||||
|  | 
 | ||||||
|     TTY(unsigned major, unsigned minor); |     TTY(unsigned major, unsigned minor); | ||||||
|     void emit(byte); |     void emit(byte); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -741,7 +741,7 @@ ssize_t Task::sys$get_dir_entries(int fd, void* buffer, size_t size) | ||||||
|     VALIDATE_USER_BUFFER(buffer, size); |     VALIDATE_USER_BUFFER(buffer, size); | ||||||
|     auto* handle = fileHandleIfExists(fd); |     auto* handle = fileHandleIfExists(fd); | ||||||
|     if (!handle) |     if (!handle) | ||||||
|         return -1; |         return -EBADF; | ||||||
|     return handle->get_dir_entries((byte*)buffer, size); |     return handle->get_dir_entries((byte*)buffer, size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -749,10 +749,25 @@ int Task::sys$seek(int fd, int offset) | ||||||
| { | { | ||||||
|     auto* handle = fileHandleIfExists(fd); |     auto* handle = fileHandleIfExists(fd); | ||||||
|     if (!handle) |     if (!handle) | ||||||
|         return -1; |         return -EBADF; | ||||||
|     return handle->seek(offset, SEEK_SET); |     return handle->seek(offset, SEEK_SET); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int Task::sys$ttyname_r(int fd, char* buffer, size_t size) | ||||||
|  | { | ||||||
|  |     VALIDATE_USER_BUFFER(buffer, size); | ||||||
|  |     auto* handle = fileHandleIfExists(fd); | ||||||
|  |     if (!handle) | ||||||
|  |         return -EBADF; | ||||||
|  |     if (!handle->isTTY()) | ||||||
|  |         return -ENOTTY; | ||||||
|  |     auto ttyName = handle->tty()->ttyName(); | ||||||
|  |     if (size < ttyName.length() + 1) | ||||||
|  |         return -ERANGE; | ||||||
|  |     strcpy(buffer, ttyName.characters()); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| ssize_t Task::sys$write(int fd, const void* data, size_t size) | ssize_t Task::sys$write(int fd, const void* data, size_t size) | ||||||
| { | { | ||||||
|     VALIDATE_USER_BUFFER(data, size); |     VALIDATE_USER_BUFFER(data, size); | ||||||
|  | @ -802,7 +817,7 @@ int Task::sys$close(int fd) | ||||||
| { | { | ||||||
|     auto* handle = fileHandleIfExists(fd); |     auto* handle = fileHandleIfExists(fd); | ||||||
|     if (!handle) |     if (!handle) | ||||||
|         return -1; |         return -EBADF; | ||||||
|     // FIXME: Implement.
 |     // FIXME: Implement.
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -111,6 +111,7 @@ public: | ||||||
|     int sys$get_arguments(int* argc, char*** argv); |     int sys$get_arguments(int* argc, char*** argv); | ||||||
|     int sys$uname(utsname*); |     int sys$uname(utsname*); | ||||||
|     int sys$readlink(const char*, char*, size_t); |     int sys$readlink(const char*, char*, size_t); | ||||||
|  |     int sys$ttyname_r(int fd, char*, size_t); | ||||||
| 
 | 
 | ||||||
|     static void initialize(); |     static void initialize(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,6 +38,20 @@ ssize_t write(int fd, const void* buf, size_t count) | ||||||
|     __RETURN_WITH_ERRNO(rc, rc, -1); |     __RETURN_WITH_ERRNO(rc, rc, -1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int ttyname_r(int fd, char* buffer, size_t size) | ||||||
|  | { | ||||||
|  |     int rc = Syscall::invoke(Syscall::PosixTtynameR, (dword)fd, (dword)buffer, (dword)size); | ||||||
|  |     __RETURN_WITH_ERRNO(rc, rc, -1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char ttyname_buf[32]; | ||||||
|  | char* ttyname(int fd) | ||||||
|  | { | ||||||
|  |     if (ttyname_r(fd, ttyname_buf, sizeof(ttyname_buf)) < 0) | ||||||
|  |         return nullptr; | ||||||
|  |     return ttyname_buf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int close(int fd) | int close(int fd) | ||||||
| { | { | ||||||
|     int rc = Syscall::invoke(Syscall::PosixClose, fd); |     int rc = Syscall::invoke(Syscall::PosixClose, fd); | ||||||
|  |  | ||||||
|  | @ -18,6 +18,8 @@ int lstat(const char* path, stat* statbuf); | ||||||
| int sleep(unsigned seconds); | int sleep(unsigned seconds); | ||||||
| int gethostname(char*, size_t); | int gethostname(char*, size_t); | ||||||
| ssize_t readlink(const char* path, char* buffer, size_t); | ssize_t readlink(const char* path, char* buffer, size_t); | ||||||
|  | char* ttyname(int fd); | ||||||
|  | int ttyname_r(int fd, char* buffer, size_t); | ||||||
| 
 | 
 | ||||||
| #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) | #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) | ||||||
| #define WTERMSIG(status) ((status) & 0x7f) | #define WTERMSIG(status) ((status) & 0x7f) | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| #include <LibC/errno.h> | #include <LibC/errno.h> | ||||||
| #include <LibC/string.h> | #include <LibC/string.h> | ||||||
| #include <LibC/stdlib.h> | #include <LibC/stdlib.h> | ||||||
|  | #include <LibC/utsname.h> | ||||||
| #include <AK/FileSystemPath.h> | #include <AK/FileSystemPath.h> | ||||||
| 
 | 
 | ||||||
| struct GlobalState { | struct GlobalState { | ||||||
|  | @ -148,6 +149,17 @@ static int runcmd(char* cmd) | ||||||
|     return retval; |     return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void greeting() | ||||||
|  | { | ||||||
|  |     utsname uts; | ||||||
|  |     int rc = uname(&uts); | ||||||
|  |     if (rc < 0) { | ||||||
|  |         perror("uname"); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     printf("\n%s/%s on %s\n\n", uts.sysname, uts.machine, ttyname(0)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int main(int, char**) | int main(int, char**) | ||||||
| { | { | ||||||
|     g = new GlobalState; |     g = new GlobalState; | ||||||
|  | @ -155,6 +167,8 @@ int main(int, char**) | ||||||
|     if (rc < 0) |     if (rc < 0) | ||||||
|         perror("gethostname"); |         perror("gethostname"); | ||||||
| 
 | 
 | ||||||
|  |     greeting(); | ||||||
|  | 
 | ||||||
|     char linebuf[128]; |     char linebuf[128]; | ||||||
|     int linedx = 0; |     int linedx = 0; | ||||||
|     linebuf[0] = '\0'; |     linebuf[0] = '\0'; | ||||||
|  |  | ||||||
|  | @ -18,6 +18,8 @@ public: | ||||||
|     unsigned major() const { return m_major; } |     unsigned major() const { return m_major; } | ||||||
|     unsigned minor() const { return m_minor; } |     unsigned minor() const { return m_minor; } | ||||||
| 
 | 
 | ||||||
|  |     virtual bool isTTY() const { return false; } | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
|     CharacterDevice(unsigned major, unsigned minor) : m_major(major), m_minor(minor) { } |     CharacterDevice(unsigned major, unsigned minor) : m_major(major), m_minor(minor) { } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include "CharacterDevice.h" | #include "CharacterDevice.h" | ||||||
| #include "sys-errno.h" | #include "sys-errno.h" | ||||||
| #include "UnixTypes.h" | #include "UnixTypes.h" | ||||||
|  | #include "TTY.h" | ||||||
| #include <AK/BufferStream.h> | #include <AK/BufferStream.h> | ||||||
| 
 | 
 | ||||||
| FileHandle::FileHandle(RetainPtr<VirtualFileSystem::Node>&& vnode) | FileHandle::FileHandle(RetainPtr<VirtualFileSystem::Node>&& vnode) | ||||||
|  | @ -109,6 +110,7 @@ Unix::ssize_t FileHandle::write(const byte* data, Unix::size_t size) | ||||||
|     } |     } | ||||||
|     // FIXME: Implement non-device writes.
 |     // FIXME: Implement non-device writes.
 | ||||||
|     ASSERT_NOT_REACHED(); |     ASSERT_NOT_REACHED(); | ||||||
|  |     return -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool FileHandle::hasDataAvailableForRead() | bool FileHandle::hasDataAvailableForRead() | ||||||
|  | @ -160,3 +162,17 @@ ssize_t FileHandle::get_dir_entries(byte* buffer, Unix::size_t size) | ||||||
|     memcpy(buffer, tempBuffer.pointer(), stream.offset()); |     memcpy(buffer, tempBuffer.pointer(), stream.offset()); | ||||||
|     return stream.offset(); |     return stream.offset(); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | bool FileHandle::isTTY() const | ||||||
|  | { | ||||||
|  |     if (auto* device = m_vnode->characterDevice()) | ||||||
|  |         return device->isTTY(); | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const TTY* FileHandle::tty() const | ||||||
|  | { | ||||||
|  |     if (auto* device = m_vnode->characterDevice()) | ||||||
|  |         return static_cast<const TTY*>(device); | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ | ||||||
| #include "InodeMetadata.h" | #include "InodeMetadata.h" | ||||||
| #include <AK/ByteBuffer.h> | #include <AK/ByteBuffer.h> | ||||||
| 
 | 
 | ||||||
|  | class TTY; | ||||||
|  | 
 | ||||||
| class FileHandle { | class FileHandle { | ||||||
| public: | public: | ||||||
|     explicit FileHandle(RetainPtr<VirtualFileSystem::Node>&&); |     explicit FileHandle(RetainPtr<VirtualFileSystem::Node>&&); | ||||||
|  | @ -24,6 +26,9 @@ public: | ||||||
| 
 | 
 | ||||||
|     bool isDirectory() const; |     bool isDirectory() const; | ||||||
| 
 | 
 | ||||||
|  |     bool isTTY() const; | ||||||
|  |     const TTY* tty() const; | ||||||
|  | 
 | ||||||
|     InodeMetadata metadata() const { return m_vnode->metadata(); } |     InodeMetadata metadata() const { return m_vnode->metadata(); } | ||||||
| 
 | 
 | ||||||
|     VirtualFileSystem::Node* vnode() { return m_vnode.ptr(); } |     VirtualFileSystem::Node* vnode() { return m_vnode.ptr(); } | ||||||
|  |  | ||||||
|  | @ -55,6 +55,7 @@ public: | ||||||
| 
 | 
 | ||||||
|         bool isCharacterDevice() const { return m_characterDevice; } |         bool isCharacterDevice() const { return m_characterDevice; } | ||||||
|         CharacterDevice* characterDevice() { return m_characterDevice; } |         CharacterDevice* characterDevice() { return m_characterDevice; } | ||||||
|  |         const CharacterDevice* characterDevice() const { return m_characterDevice; } | ||||||
| 
 | 
 | ||||||
|         void retain(); |         void retain(); | ||||||
|         void release(); |         void release(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling