diff options
-rw-r--r-- | Kernel/Process.cpp | 24 | ||||
-rw-r--r-- | Kernel/Process.h | 1 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscall.h | 1 | ||||
-rwxr-xr-x | Kernel/sync.sh | 1 | ||||
-rw-r--r-- | LibC/Makefile | 1 | ||||
-rw-r--r-- | LibC/utime.cpp | 14 | ||||
-rw-r--r-- | LibC/utime.h | 10 | ||||
-rw-r--r-- | Userland/.gitignore | 1 | ||||
-rw-r--r-- | Userland/Makefile | 9 | ||||
-rw-r--r-- | Userland/ls.cpp | 2 | ||||
-rw-r--r-- | Userland/touch.cpp | 16 | ||||
-rw-r--r-- | VirtualFileSystem/Ext2FileSystem.cpp | 10 | ||||
-rw-r--r-- | VirtualFileSystem/Ext2FileSystem.h | 2 | ||||
-rw-r--r-- | VirtualFileSystem/FileDescriptor.cpp | 14 | ||||
-rw-r--r-- | VirtualFileSystem/FileDescriptor.h | 4 | ||||
-rw-r--r-- | VirtualFileSystem/FileSystem.cpp | 5 | ||||
-rw-r--r-- | VirtualFileSystem/FileSystem.h | 4 | ||||
-rw-r--r-- | VirtualFileSystem/SyntheticFileSystem.cpp | 7 | ||||
-rw-r--r-- | VirtualFileSystem/SyntheticFileSystem.h | 2 | ||||
-rw-r--r-- | VirtualFileSystem/UnixTypes.h | 5 | ||||
-rw-r--r-- | VirtualFileSystem/VirtualFileSystem.cpp | 9 |
22 files changed, 122 insertions, 22 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 1a92f1ea7c..3e1048e9be 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1079,6 +1079,30 @@ int Process::sys$close(int fd) return rc; } +int Process::sys$utime(const char* pathname, const Unix::utimbuf* buf) +{ + if (!validate_read_str(pathname)) + return -EFAULT; + if (buf && !validate_read_typed(buf)) + return -EFAULT; + String path(pathname); + int error; + auto descriptor = VFS::the().open(move(path), error, 0, cwd_inode()->identifier()); + if (!descriptor) + return error; + Unix::time_t atime; + Unix::time_t mtime; + if (buf) { + atime = buf->actime; + mtime = buf->modtime; + } else { + auto now = RTC::now(); + mtime = now; + atime = now; + } + return descriptor->set_atime_and_mtime(atime, mtime); +} + int Process::sys$access(const char* pathname, int mode) { (void) mode; diff --git a/Kernel/Process.h b/Kernel/Process.h index 3e7038b6ab..ffb51aa3f1 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -173,6 +173,7 @@ public: int sys$ioctl(int fd, unsigned request, unsigned arg); int sys$mkdir(const char* pathname, mode_t mode); Unix::clock_t sys$times(Unix::tms*); + int sys$utime(const char* pathname, const struct Unix::utimbuf*); static void initialize(); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 0d83459de1..0c9d8b472f 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -177,6 +177,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, return current->sys$mkdir((const char*)arg1, (mode_t)arg2); case Syscall::SC_times: return current->sys$times((Unix::tms*)arg1); + case Syscall::SC_utime: + return current->sys$utime((const char*)arg1, (const Unix::utimbuf*)arg2); default: kprintf("<%u> int0x80: Unknown function %u requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3); break; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 81717dbda6..99a0c73730 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -64,6 +64,7 @@ __ENUMERATE_SYSCALL(ioctl) \ __ENUMERATE_SYSCALL(mkdir) \ __ENUMERATE_SYSCALL(times) \ + __ENUMERATE_SYSCALL(utime) \ #define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function)) diff --git a/Kernel/sync.sh b/Kernel/sync.sh index 130ceba83c..49ed14e7e3 100755 --- a/Kernel/sync.sh +++ b/Kernel/sync.sh @@ -30,6 +30,7 @@ cp -v ../Userland/kill mnt/bin/kill cp -v ../Userland/tty mnt/bin/tty cp -v ../Userland/strsignal mnt/bin/strsignal cp -v ../Userland/mkdir mnt/bin/mkdir +cp -v ../Userland/touch mnt/bin/touch sh sync-local.sh cp -v kernel.map mnt/ ln -s dir_a mnt/dir_cur diff --git a/LibC/Makefile b/LibC/Makefile index 1ffaf65262..55e182162f 100644 --- a/LibC/Makefile +++ b/LibC/Makefile @@ -32,6 +32,7 @@ LIBC_OBJS = \ qsort.o \ ioctl.o \ math.o \ + utime.o \ entry.o OBJS = $(AK_OBJS) $(LIBC_OBJS) diff --git a/LibC/utime.cpp b/LibC/utime.cpp new file mode 100644 index 0000000000..310d06c32a --- /dev/null +++ b/LibC/utime.cpp @@ -0,0 +1,14 @@ +#include <utime.h> +#include <errno.h> +#include <Kernel/Syscall.h> + +extern "C" { + +int utime(const char* pathname, const struct utimbuf* buf) +{ + int rc = Syscall::invoke(Syscall::SC_utime, (dword)pathname, (dword)buf); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + +} + diff --git a/LibC/utime.h b/LibC/utime.h index e69de29bb2..96c26f6bb4 100644 --- a/LibC/utime.h +++ b/LibC/utime.h @@ -0,0 +1,10 @@ +#pragma once + +#include <sys/cdefs.h> + +__BEGIN_DECLS + +int utime(const char* pathname, const struct utimbuf*); + +__END_DECLS + diff --git a/Userland/.gitignore b/Userland/.gitignore index 5bb5aee8b9..c5f95143dc 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -21,3 +21,4 @@ ft2 strsignal fgrep mkdir +touch diff --git a/Userland/Makefile b/Userland/Makefile index e8f5195036..30abcc2e79 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -19,7 +19,8 @@ OBJS = \ strsignal.o \ fgrep.o \ tty.o \ - mkdir.o + mkdir.o \ + touch.o APPS = \ id \ @@ -42,7 +43,8 @@ APPS = \ strsignal \ fgrep \ tty \ - mkdir + mkdir \ + touch ARCH_FLAGS = STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib -nostdinc @@ -125,6 +127,9 @@ strsignal: strsignal.o mkdir: mkdir.o $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a +touch: touch.o + $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a + .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Userland/ls.cpp b/Userland/ls.cpp index edcacb8971..622dc928cc 100644 --- a/Userland/ls.cpp +++ b/Userland/ls.cpp @@ -152,6 +152,8 @@ int do_dir(const char* path) printf(" %10u ", st.st_size); + printf(" %10u ", st.st_mtime); + print_name(st, de->d_name, pathbuf); printf("\n"); diff --git a/Userland/touch.cpp b/Userland/touch.cpp new file mode 100644 index 0000000000..6d857198f6 --- /dev/null +++ b/Userland/touch.cpp @@ -0,0 +1,16 @@ +#include <stdio.h> +#include <utime.h> +#include <sys/types.h> + +int main(int argc, char** argv) +{ + if (argc != 2) { + fprintf(stderr, "usage: touch <path>\n"); + return 1; + } + int rc = utime(argv[1], nullptr); + if (rc < 0) + perror("utime"); + return 0; +} + diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index 9a07560d64..a5aa753d90 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -716,16 +716,18 @@ bool Ext2FS::modify_link_count(InodeIndex inode, int delta) return write_ext2_inode(inode, *e2inode); } -bool Ext2FS::set_mtime(InodeIdentifier inode, dword timestamp) +int Ext2FS::set_atime_and_mtime(InodeIdentifier inode, dword atime, dword mtime) { ASSERT(inode.fsid() == id()); auto e2inode = lookup_ext2_inode(inode.index()); if (!e2inode) - return false; + return -EIO; - kprintf("changing inode %u mtime from %u to %u\n", inode.index(), e2inode->i_mtime, timestamp); - e2inode->i_mtime = timestamp; + dbgprintf("changing inode %u atime from %u to %u\n", inode.index(), e2inode->i_atime, atime); + dbgprintf("changing inode %u mtime from %u to %u\n", inode.index(), e2inode->i_mtime, mtime); + e2inode->i_mtime = mtime; + e2inode->i_atime = atime; return write_ext2_inode(inode.index(), *e2inode); } diff --git a/VirtualFileSystem/Ext2FileSystem.h b/VirtualFileSystem/Ext2FileSystem.h index 71283b229b..5b317054c6 100644 --- a/VirtualFileSystem/Ext2FileSystem.h +++ b/VirtualFileSystem/Ext2FileSystem.h @@ -72,7 +72,7 @@ private: virtual InodeIdentifier root_inode() const override; virtual bool write_inode(InodeIdentifier, const ByteBuffer&) override; virtual InodeMetadata inode_metadata(InodeIdentifier) const override; - virtual bool set_mtime(InodeIdentifier, dword timestamp) override; + virtual int set_atime_and_mtime(InodeIdentifier, dword atime, dword mtime) override; virtual InodeIdentifier create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) override; virtual ssize_t read_inode_bytes(InodeIdentifier, Unix::off_t offset, size_t count, byte* buffer, FileDescriptor*) const override; virtual InodeIdentifier create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) override; diff --git a/VirtualFileSystem/FileDescriptor.cpp b/VirtualFileSystem/FileDescriptor.cpp index 6ec2bdd440..12e8dcd413 100644 --- a/VirtualFileSystem/FileDescriptor.cpp +++ b/VirtualFileSystem/FileDescriptor.cpp @@ -288,3 +288,17 @@ FileDescriptor::FileDescriptor(FIFO& fifo, FIFO::Direction direction) { m_fifo->open(direction); } + +int FileDescriptor::set_atime_and_mtime(time_t atime, time_t mtime) +{ + if (!m_vnode || !m_vnode->core_inode()) + return -EBADF; + return m_vnode->core_inode()->set_atime_and_mtime(atime, mtime); +} + +int FileDescriptor::set_ctime(time_t ctime) +{ + (void) ctime; + // FIXME: Implement. + ASSERT_NOT_REACHED(); +} diff --git a/VirtualFileSystem/FileDescriptor.h b/VirtualFileSystem/FileDescriptor.h index ee81266074..0152a189c9 100644 --- a/VirtualFileSystem/FileDescriptor.h +++ b/VirtualFileSystem/FileDescriptor.h @@ -64,13 +64,15 @@ public: ByteBuffer& generator_cache() { return m_generator_cache; } + int set_atime_and_mtime(time_t, time_t); + int set_ctime(time_t); + private: friend class VFS; explicit FileDescriptor(RetainPtr<Vnode>&&); FileDescriptor(FIFO&, FIFO::Direction); RetainPtr<Vnode> m_vnode; - RetainPtr<CoreInode> m_inode; Unix::off_t m_current_offset { 0 }; diff --git a/VirtualFileSystem/FileSystem.cpp b/VirtualFileSystem/FileSystem.cpp index a5444292eb..460b58881b 100644 --- a/VirtualFileSystem/FileSystem.cpp +++ b/VirtualFileSystem/FileSystem.cpp @@ -127,3 +127,8 @@ FS::DirectoryEntry::DirectoryEntry(const char* n, size_t nl, InodeIdentifier i, CoreInode::~CoreInode() { } + +int CoreInode::set_atime_and_mtime(Unix::time_t atime, Unix::time_t mtime) +{ + return fs().set_atime_and_mtime(identifier(), atime, mtime); +} diff --git a/VirtualFileSystem/FileSystem.h b/VirtualFileSystem/FileSystem.h index d1f8f67611..40a4002e54 100644 --- a/VirtualFileSystem/FileSystem.h +++ b/VirtualFileSystem/FileSystem.h @@ -44,7 +44,7 @@ public: byte fileType { 0 }; }; - virtual bool set_mtime(InodeIdentifier, dword timestamp) = 0; + virtual int set_atime_and_mtime(InodeIdentifier, dword atime, dword mtime) = 0; virtual InodeIdentifier create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) = 0; virtual InodeIdentifier create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) = 0; @@ -85,6 +85,8 @@ public: virtual InodeIdentifier lookup(const String& name) = 0; virtual String reverse_lookup(InodeIdentifier) = 0; + int set_atime_and_mtime(Unix::time_t atime, Unix::time_t mtime); + protected: CoreInode(FS& fs, unsigned index) : m_fs(fs) diff --git a/VirtualFileSystem/SyntheticFileSystem.cpp b/VirtualFileSystem/SyntheticFileSystem.cpp index 526d3489f4..aeb122fbc0 100644 --- a/VirtualFileSystem/SyntheticFileSystem.cpp +++ b/VirtualFileSystem/SyntheticFileSystem.cpp @@ -146,11 +146,12 @@ InodeMetadata SynthFS::inode_metadata(InodeIdentifier inode) const return (*it).value->m_metadata; } -bool SynthFS::set_mtime(InodeIdentifier, dword timestamp) +int SynthFS::set_atime_and_mtime(InodeIdentifier, dword atime, dword mtime) { - (void) timestamp; + (void) atime; + (void) mtime; kprintf("FIXME: Implement SyntheticFileSystem::setModificationTime().\n"); - return false; + return -ENOTIMPL; } InodeIdentifier SynthFS::create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t mode, unsigned size, int& error) diff --git a/VirtualFileSystem/SyntheticFileSystem.h b/VirtualFileSystem/SyntheticFileSystem.h index 2901794368..ba907d0d3b 100644 --- a/VirtualFileSystem/SyntheticFileSystem.h +++ b/VirtualFileSystem/SyntheticFileSystem.h @@ -16,7 +16,7 @@ public: virtual InodeIdentifier root_inode() const override; virtual bool write_inode(InodeIdentifier, const ByteBuffer&) override; virtual InodeMetadata inode_metadata(InodeIdentifier) const override; - virtual bool set_mtime(InodeIdentifier, dword timestamp) override; + virtual int set_atime_and_mtime(InodeIdentifier, dword atime, dword mtime) override; virtual InodeIdentifier create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) override; virtual ssize_t read_inode_bytes(InodeIdentifier, Unix::off_t offset, size_t count, byte* buffer, FileDescriptor*) const override; virtual InodeIdentifier create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) override; diff --git a/VirtualFileSystem/UnixTypes.h b/VirtualFileSystem/UnixTypes.h index f90e860847..765dfe67ec 100644 --- a/VirtualFileSystem/UnixTypes.h +++ b/VirtualFileSystem/UnixTypes.h @@ -264,6 +264,11 @@ typedef signed_qword off_t; typedef ::time_t time_t; #endif +struct utimbuf { + time_t actime; + time_t modtime; +}; + typedef dword blksize_t; typedef dword blkcnt_t; diff --git a/VirtualFileSystem/VirtualFileSystem.cpp b/VirtualFileSystem/VirtualFileSystem.cpp index 5c14d9700e..79568d4d89 100644 --- a/VirtualFileSystem/VirtualFileSystem.cpp +++ b/VirtualFileSystem/VirtualFileSystem.cpp @@ -252,15 +252,6 @@ void VFS::traverse_directory_inode(CoreInode& dir_inode, Function<bool(const FS: }); } -bool VFS::touch(const String& path) -{ - int error; - auto inode = resolve_path(path, root_inode_id(), error); - if (!inode.is_valid()) - return false; - return inode.fs()->set_mtime(inode, ktime(nullptr)); -} - RetainPtr<FileDescriptor> VFS::open(CharacterDevice& device, int options) { // FIXME: Respect options. |