sortix-mirror/kernel/include/sortix/kernel/descriptor.h

160 lines
5.9 KiB
C
Raw Normal View History

/*
* Copyright (c) 2012-2017, 2021 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* sortix/kernel/descriptor.h
* A file descriptor.
*/
#ifndef INCLUDE_SORTIX_KERNEL_DESCRIPTOR_H
#define INCLUDE_SORTIX_KERNEL_DESCRIPTOR_H
#include <sys/types.h>
#include <stdint.h>
#include <sortix/timespec.h>
#include <sortix/kernel/kthread.h>
#include <sortix/kernel/refcount.h>
2015-11-20 01:57:09 +00:00
struct dirent;
struct iovec;
struct msghdr;
struct stat;
struct statvfs;
2016-01-23 19:56:07 +00:00
struct termios;
2013-12-20 20:55:05 +00:00
struct wincurpos;
struct winsize;
namespace Sortix {
2012-12-29 22:09:09 +00:00
class PollNode;
class Inode;
class Vnode;
struct ioctx_struct;
typedef struct ioctx_struct ioctx_t;
class Descriptor : public Refcountable
{
2014-05-07 12:14:38 +00:00
private:
Descriptor();
void LateConstruct(Ref<Vnode> vnode, int dflags);
public:
Descriptor(Ref<Vnode> vnode, int dflags);
virtual ~Descriptor();
Ref<Descriptor> Fork();
bool SetFlags(int new_dflags);
int GetFlags();
bool pass();
void unpass();
int sync(ioctx_t* ctx);
int stat(ioctx_t* ctx, struct stat* st);
int statvfs(ioctx_t* ctx, struct statvfs* stvfs);
int chmod(ioctx_t* ctx, mode_t mode);
int chown(ioctx_t* ctx, uid_t owner, gid_t group);
int truncate(ioctx_t* ctx, off_t length);
off_t lseek(ioctx_t* ctx, off_t offset, int whence);
ssize_t read(ioctx_t* ctx, uint8_t* buf, size_t count);
ssize_t readv(ioctx_t* ctx, const struct iovec* iov, int iovcnt);
ssize_t pread(ioctx_t* ctx, uint8_t* buf, size_t count, off_t off);
ssize_t preadv(ioctx_t* ctx, const struct iovec* iov, int iovcnt,
off_t off);
ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count);
ssize_t writev(ioctx_t* ctx, const struct iovec* iov, int iovcnt);
ssize_t pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count, off_t off);
ssize_t pwritev(ioctx_t* ctx, const struct iovec* iov, int iovcnt,
off_t off);
2016-02-24 15:29:37 +00:00
int utimens(ioctx_t* ctx, const struct timespec* times);
int isatty(ioctx_t* ctx);
2015-11-20 01:57:09 +00:00
ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, size_t size);
Ref<Descriptor> open(ioctx_t* ctx, const char* filename, int flags,
mode_t mode = 0);
int mkdir(ioctx_t* ctx, const char* filename, mode_t mode);
int link(ioctx_t* ctx, const char* filename, Ref<Descriptor> node);
int unlinkat(ioctx_t* ctx, const char* filename, int flags);
int symlink(ioctx_t* ctx, const char* oldname, const char* filename);
ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
2013-12-20 20:55:05 +00:00
int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp);
int ioctl(ioctx_t* ctx, int cmd, uintptr_t arg);
2013-06-12 00:18:07 +00:00
int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
pid_t tcgetpgrp(ioctx_t* ctx);
int settermmode(ioctx_t* ctx, unsigned mode);
int gettermmode(ioctx_t* ctx, unsigned* mode);
2012-12-29 22:09:09 +00:00
int poll(ioctx_t* ctx, PollNode* node);
2012-12-20 15:19:07 +00:00
int rename_here(ioctx_t* ctx, Ref<Descriptor> from, const char* oldpath,
const char* newpath);
Ref<Descriptor> accept4(ioctx_t* ctx, uint8_t* addr, size_t* addrlen,
int flags);
2013-03-19 21:40:37 +00:00
int bind(ioctx_t* ctx, const uint8_t* addr, size_t addrlen);
int connect(ioctx_t* ctx, const uint8_t* addr, size_t addrlen);
int listen(ioctx_t* ctx, int backlog);
ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags);
ssize_t recvmsg(ioctx_t* ctx, struct msghdr* msg, int flags);
2013-03-19 21:40:37 +00:00
ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count, int flags);
ssize_t sendmsg(ioctx_t* ctx, const struct msghdr* msg, int flags);
2014-02-28 16:10:08 +00:00
int getsockopt(ioctx_t* ctx, int level, int option_name,
void* option_value, size_t* option_size_ptr);
int setsockopt(ioctx_t* ctx, int level, int option_name,
const void* option_value, size_t option_size);
2014-05-05 19:36:40 +00:00
ssize_t tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count);
ssize_t tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count);
2014-05-07 12:14:38 +00:00
int unmount(ioctx_t* ctx, const char* filename, int flags);
int fsm_fsbind(ioctx_t* ctx, Ref<Descriptor> target, int flags);
Ref<Descriptor> fsm_mount(ioctx_t* ctx, const char* filename,
const struct stat* rootst, int flags);
2016-01-23 19:56:07 +00:00
int tcdrain(ioctx_t* ctx);
int tcflow(ioctx_t* ctx, int action);
int tcflush(ioctx_t* ctx, int queue_selector);
int tcgetattr(ioctx_t* ctx, struct termios* tio);
pid_t tcgetsid(ioctx_t* ctx);
int tcsendbreak(ioctx_t* ctx, int duration);
int tcsetattr(ioctx_t* ctx, int actions, const struct termios* tio);
2016-08-06 13:44:37 +00:00
int shutdown(ioctx_t* ctx, int how);
int getpeername(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
int getsockname(ioctx_t* ctx, uint8_t* addr, size_t* addrsize);
private:
Ref<Descriptor> open_elem(ioctx_t* ctx, const char* filename, int flags,
mode_t mode);
bool IsSeekable();
public: /* These must never change after construction. */
ino_t ino;
dev_t dev;
mode_t type; // For use by S_IS* macros.
public:
Ref<Vnode> vnode;
private:
kthread_mutex_t current_offset_lock;
off_t current_offset;
int dflags;
bool seekable;
bool checked_seekable;
};
int LinkInodeInDir(ioctx_t* ctx, Ref<Descriptor> dir, const char* name,
Ref<Inode> inode);
Ref<Descriptor> OpenDirContainingPath(ioctx_t* ctx, Ref<Descriptor> from,
const char* path, char** finalp);
Fix SEEK_END, file offset overflow, and read/write/mkpartition syscall bugs. Fix SEEK_END seeking twice as far as requested. Centralize lseek handling in one place and avoid overflow bugs. Inode lseek handlers now only need to handle SEEK_END with offset 0. Prevent the file offset from ever going below zero or overflowing. Character devices are now not seekable, but lseek will pretend they are, yet always stay at the file offset 0. pread/pwrite on character devices will now ignore the file offset and call read/write. This change prevents character devices from being memory mapped, notably /dev/zero can no longer be memory mapped. None of the current ports seem to rely on this behavior and will work with just MAP_ANONYMOUS. Refactor read and write system calls to have a shared return statement for both seekable and non-seekable IO. Fix file offset overflow bugs in read and write system calls. Fix system calls returning EPERM instead of properly returning EBADF when the file has not been opened in the right mode. Truncate IO counts and total vector IO length so the IO operation does not do any IO beyond OFF_MAX. Truncate also total vector IO length for recvmsg and sendmsg. Fail with EINVAL if total vector IO length exceeds SSIZE_MAX. Don't stop early if the total IO length is zero, so zero length IO now block on any locks internal to the inode. Handle reads at the maximum file offset with an end of file condition and handle writes of at least one byte at the maximum file offset by failing with EFBIG. Refactor UtilMemoryBuffer to store the file size using off_t instead of size_t to avoid casts and keep file sizes in the off_t type. Properly handle errors in the code, such as failing with EROFS instead of EBADF if the backing memory is not writeable, and failing with EFBIG if writing beyond the end of the file. Fix mkpartition not rejecting invalid partition start offsets and lengths. Strictly enforce partition start and length checks in the partition code. Enforce partitions exist within regular files or block devices. Fix a few indention issues.
2017-10-26 15:12:07 +00:00
size_t TruncateIOVec(struct iovec* iov, int iovcnt, off_t limit);
} // namespace Sortix
#endif