summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Process.cpp24
-rw-r--r--Kernel/Process.h1
-rw-r--r--Kernel/Syscall.cpp2
-rw-r--r--Kernel/Syscall.h1
-rwxr-xr-xKernel/sync.sh1
-rw-r--r--LibC/Makefile1
-rw-r--r--LibC/utime.cpp14
-rw-r--r--LibC/utime.h10
-rw-r--r--Userland/.gitignore1
-rw-r--r--Userland/Makefile9
-rw-r--r--Userland/ls.cpp2
-rw-r--r--Userland/touch.cpp16
-rw-r--r--VirtualFileSystem/Ext2FileSystem.cpp10
-rw-r--r--VirtualFileSystem/Ext2FileSystem.h2
-rw-r--r--VirtualFileSystem/FileDescriptor.cpp14
-rw-r--r--VirtualFileSystem/FileDescriptor.h4
-rw-r--r--VirtualFileSystem/FileSystem.cpp5
-rw-r--r--VirtualFileSystem/FileSystem.h4
-rw-r--r--VirtualFileSystem/SyntheticFileSystem.cpp7
-rw-r--r--VirtualFileSystem/SyntheticFileSystem.h2
-rw-r--r--VirtualFileSystem/UnixTypes.h5
-rw-r--r--VirtualFileSystem/VirtualFileSystem.cpp9
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.