summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AK/String.h10
-rw-r--r--Kernel/Syscall.cpp2
-rw-r--r--Kernel/Syscall.h1
-rw-r--r--Kernel/Task.cpp28
-rw-r--r--Kernel/Task.h9
-rw-r--r--Kernel/_fs_contentsbin1024000 -> 1024000 bytes
-rw-r--r--Kernel/init.cpp2
-rwxr-xr-xKernel/sync-sh1
-rw-r--r--LibC/unistd.cpp8
-rw-r--r--LibC/unistd.h4
-rw-r--r--Userland/.gitignore1
-rw-r--r--Userland/Makefile9
-rw-r--r--Userland/pwd.cpp15
-rw-r--r--VirtualFileSystem/FileHandle.cpp3
-rw-r--r--VirtualFileSystem/FileHandle.h2
-rw-r--r--VirtualFileSystem/InodeIdentifier.h5
-rw-r--r--VirtualFileSystem/VirtualFileSystem.h1
17 files changed, 87 insertions, 14 deletions
diff --git a/AK/String.h b/AK/String.h
index 4def06f2e6..96a193a331 100644
--- a/AK/String.h
+++ b/AK/String.h
@@ -76,9 +76,15 @@ public:
String& operator=(String&& other)
{
- if (this != &other) {
+ if (this != &other)
m_impl = move(other.m_impl);
- }
+ return *this;
+ }
+
+ String& operator=(const String& other)
+ {
+ if (this != &other)
+ m_impl = const_cast<String&>(other).m_impl.copyRef();
return *this;
}
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp
index 846c1b99ea..538b635d15 100644
--- a/Kernel/Syscall.cpp
+++ b/Kernel/Syscall.cpp
@@ -70,6 +70,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
return current->sys$get_dir_entries((int)arg1, (void*)arg2, (size_t)arg3);
case Syscall::PosixLstat:
return current->sys$lstat((const char*)arg1, (void*)arg2);
+ case Syscall::PosixGetcwd:
+ return current->sys$getcwd((char*)arg1, (size_t)arg2);
case Syscall::PosixOpen:
//kprintf("syscall: open('%s', %u)\n", arg1, arg2);
return current->sys$open((const char*)arg1, (size_t)arg2);
diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h
index ff0b8af69e..bef6d5ff36 100644
--- a/Kernel/Syscall.h
+++ b/Kernel/Syscall.h
@@ -28,6 +28,7 @@ enum Function {
PosixMunmap = 0x1996,
GetDirEntries = 0x1997,
PosixLstat = 0x1998,
+ PosixGetcwd = 0x1999,
};
void initialize();
diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp
index 7005394ee5..50bc885708 100644
--- a/Kernel/Task.cpp
+++ b/Kernel/Task.cpp
@@ -165,13 +165,13 @@ int Task::sys$munmap(void* addr, size_t size)
int Task::sys$spawn(const char* path)
{
- auto* child = Task::create(path, m_uid, m_gid);
+ auto* child = Task::create(path, m_uid, m_gid, m_pid);
if (child)
return child->pid();
return -1;
}
-Task* Task::create(const String& path, uid_t uid, gid_t gid)
+Task* Task::create(const String& path, uid_t uid, gid_t gid, pid_t parentPID)
{
auto parts = path.split('/');
if (parts.isEmpty())
@@ -186,7 +186,7 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid)
return nullptr;
InterruptDisabler disabler; // FIXME: Get rid of this, jesus christ. This "critical" section is HUGE.
- Task* t = new Task(parts.takeLast(), uid, gid);
+ Task* t = new Task(parts.takeLast(), uid, gid, parentPID);
ExecSpace space;
space.hookableAlloc = [&] (const String& name, size_t size) {
@@ -222,18 +222,25 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid)
return t;
}
-Task::Task(String&& name, uid_t uid, gid_t gid)
+Task::Task(String&& name, uid_t uid, gid_t gid, pid_t parentPID)
: m_name(move(name))
, m_pid(next_pid++)
, m_uid(uid)
, m_gid(gid)
, m_state(Runnable)
, m_ring(Ring3)
+ , m_parentPID(parentPID)
{
m_fileHandles.append(nullptr);
m_fileHandles.append(nullptr);
m_fileHandles.append(nullptr);
+ auto* parentTask = Task::fromPID(parentPID);
+ if (parentTask)
+ m_cwd = parentTask->m_cwd;
+ else
+ m_cwd = "/";
+
m_nextRegion = LinearAddress(0x600000);
memset(&m_tss, 0, sizeof(m_tss));
@@ -288,6 +295,8 @@ Task::Task(void (*e)(), const char* n, IPC::Handle h, RingLevel ring)
m_fileHandles.append(nullptr);
m_fileHandles.append(nullptr);
+ m_cwd = "/";
+
m_nextRegion = LinearAddress(0x600000);
Region* codeRegion = nullptr;
@@ -709,6 +718,17 @@ int Task::sys$lstat(const char* path, void* statbuf)
return 0;
}
+int Task::sys$getcwd(char* buffer, size_t size)
+{
+ if (size < m_cwd.length() + 1) {
+ // FIXME: return -ERANGE;
+ return -1;
+ }
+ memcpy(buffer, m_cwd.characters(), m_cwd.length());
+ buffer[m_cwd.length()] = '\0';
+ return 0;
+}
+
int Task::sys$open(const char* path, size_t pathLength)
{
Task::checkSanity("sys$open");
diff --git a/Kernel/Task.h b/Kernel/Task.h
index c7ca13eeb4..9dc8de9c1b 100644
--- a/Kernel/Task.h
+++ b/Kernel/Task.h
@@ -16,8 +16,8 @@ class Zone;
class Task : public InlineLinkedListNode<Task> {
friend class InlineLinkedListNode<Task>;
public:
- static Task* create(const String& path, uid_t, gid_t);
- Task(String&& name, uid_t, gid_t);
+ static Task* create(const String& path, uid_t, gid_t, pid_t parentPID);
+ Task(String&& name, uid_t, gid_t, pid_t parentPID);
static Vector<Task*> allTasks();
@@ -103,6 +103,7 @@ public:
void* sys$mmap(void*, size_t size);
int sys$munmap(void*, size_t size);
int sys$get_dir_entries(int fd, void*, size_t);
+ int sys$getcwd(char*, size_t);
struct
{
@@ -157,6 +158,8 @@ private:
dword m_timesScheduled { 0 };
pid_t m_waitee { -1 };
+ String m_cwd;
+
struct Region {
Region(LinearAddress, size_t, RetainPtr<Zone>&&, String&&);
~Region();
@@ -174,6 +177,8 @@ private:
// FIXME: Implement some kind of ASLR?
LinearAddress m_nextRegion;
+
+ pid_t m_parentPID { 0 };
};
extern void task_init();
diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents
index 7aacb359bb..fbf9da7dbd 100644
--- a/Kernel/_fs_contents
+++ b/Kernel/_fs_contents
Binary files differ
diff --git a/Kernel/init.cpp b/Kernel/init.cpp
index e67e92329a..99bca8f15b 100644
--- a/Kernel/init.cpp
+++ b/Kernel/init.cpp
@@ -150,7 +150,7 @@ static void init_stage2()
}
#endif
- auto* shTask = Task::create("/bin/sh", (uid_t)100, (gid_t)100);
+ auto* shTask = Task::create("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0);
banner();
diff --git a/Kernel/sync-sh b/Kernel/sync-sh
index a0f071bd68..e2d1e6cd2a 100755
--- a/Kernel/sync-sh
+++ b/Kernel/sync-sh
@@ -4,5 +4,6 @@ cp ../Userland/sh mnt/bin/sh
cp ../Userland/id mnt/bin/id
cp ../Userland/ps mnt/bin/ps
cp ../Userland/ls mnt/bin/ls
+cp ../Userland/pwd mnt/bin/pwd
umount mnt
sync
diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp
index 42e3f49c32..f0c5831940 100644
--- a/LibC/unistd.cpp
+++ b/LibC/unistd.cpp
@@ -45,5 +45,13 @@ int lstat(const char* path, stat* statbuf)
return Syscall::invoke(Syscall::PosixLstat, (dword)path, (dword)statbuf);
}
+char* getcwd(char* buffer, size_t size)
+{
+ int rc = Syscall::invoke(Syscall::PosixGetcwd, (dword)buffer, (dword)size);
+ if (rc != 0)
+ return nullptr;
+ return buffer;
+}
+
}
diff --git a/LibC/unistd.h b/LibC/unistd.h
index 7dcbe0b51f..96603a6795 100644
--- a/LibC/unistd.h
+++ b/LibC/unistd.h
@@ -11,7 +11,7 @@ int open(const char* path);
ssize_t read(int fd, void* buf, size_t count);
int close(int fd);
pid_t waitpid(pid_t);
-
+char* getcwd(char* buffer, size_t size);
int lstat(const char* path, stat* statbuf);
#define S_IFMT 0170000
@@ -36,7 +36,6 @@ int lstat(const char* path, stat* statbuf);
#define S_IWOTH 0002
#define S_IXOTH 0001
-
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
@@ -45,4 +44,3 @@ int lstat(const char* path, stat* statbuf);
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
}
-
diff --git a/Userland/.gitignore b/Userland/.gitignore
index 5f641bf9a1..ed1a6797f5 100644
--- a/Userland/.gitignore
+++ b/Userland/.gitignore
@@ -2,4 +2,5 @@ id
sh
ps
ls
+pwd
*.o
diff --git a/Userland/Makefile b/Userland/Makefile
index c1cd22033c..e47a8578b6 100644
--- a/Userland/Makefile
+++ b/Userland/Makefile
@@ -2,13 +2,15 @@ OBJS = \
id.o \
sh.o \
ps.o \
- ls.o
+ ls.o \
+ pwd.o
APPS = \
id \
sh \
ps \
- ls
+ ls \
+ pwd
ARCH_FLAGS =
STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
@@ -40,6 +42,9 @@ ps: ps.o
ls: ls.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
+pwd: pwd.o
+ $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
+
.cpp.o:
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
diff --git a/Userland/pwd.cpp b/Userland/pwd.cpp
new file mode 100644
index 0000000000..ebb7d5b6d3
--- /dev/null
+++ b/Userland/pwd.cpp
@@ -0,0 +1,15 @@
+#include <LibC/unistd.h>
+#include <LibC/stdio.h>
+
+int main(int c, char** v)
+{
+ char buffer[1024];
+ char* ptr = getcwd(buffer, sizeof(buffer));
+ if (!ptr) {
+ printf("getcwd() failed\n");
+ return 1;
+ }
+ printf("%s\n", ptr);
+ return 0;
+}
+
diff --git a/VirtualFileSystem/FileHandle.cpp b/VirtualFileSystem/FileHandle.cpp
index 90c0beade2..172fe74cf5 100644
--- a/VirtualFileSystem/FileHandle.cpp
+++ b/VirtualFileSystem/FileHandle.cpp
@@ -142,6 +142,9 @@ ssize_t FileHandle::get_dir_entries(byte* buffer, size_t size)
return true;
});
+ if (size < stream.offset())
+ return -1;
+
memcpy(buffer, tempBuffer.pointer(), stream.offset());
return stream.offset();
}
diff --git a/VirtualFileSystem/FileHandle.h b/VirtualFileSystem/FileHandle.h
index f75d88895c..0aa23b93dd 100644
--- a/VirtualFileSystem/FileHandle.h
+++ b/VirtualFileSystem/FileHandle.h
@@ -16,6 +16,8 @@ public:
ByteBuffer readEntireFile();
+ String absolutePath() const;
+
#ifdef SERENITY
int fd() const { return m_fd; }
void setFD(int fd) { m_fd = fd; }
diff --git a/VirtualFileSystem/InodeIdentifier.h b/VirtualFileSystem/InodeIdentifier.h
index 865b07f838..d985266ec6 100644
--- a/VirtualFileSystem/InodeIdentifier.h
+++ b/VirtualFileSystem/InodeIdentifier.h
@@ -28,6 +28,11 @@ public:
return m_fileSystemID == other.m_fileSystemID && m_index == other.m_index;
}
+ bool operator!=(const InodeIdentifier& other) const
+ {
+ return m_fileSystemID != other.m_fileSystemID || m_index != other.m_index;
+ }
+
InodeMetadata metadata() const;
bool isRootInode() const;
diff --git a/VirtualFileSystem/VirtualFileSystem.h b/VirtualFileSystem/VirtualFileSystem.h
index bafb791d9f..53e8fcb4a1 100644
--- a/VirtualFileSystem/VirtualFileSystem.h
+++ b/VirtualFileSystem/VirtualFileSystem.h
@@ -78,6 +78,7 @@ private:
friend class FileHandle;
void enumerateDirectoryInode(InodeIdentifier, Function<bool(const FileSystem::DirectoryEntry&)>);
+ String absolutePath(InodeIdentifier);
InodeIdentifier resolvePath(const String& path);
InodeIdentifier resolveSymbolicLink(const String& basePath, InodeIdentifier symlinkInode);