+}
+
+int
+__vfs_do_chdir(struct v_dnode* dnode)
+{
+ int errno = 0;
+ if (!(dnode->inode->itype & VFS_IFDIR)) {
+ errno = ENOTDIR;
+ goto done;
+ }
+
+ if (__current->cwd) {
+ __current->cwd->ref_count--;
+ }
+
+ dnode->ref_count++;
+ __current->cwd = dnode;
+
+done:
+ return errno;
+}
+
+__DEFINE_LXSYSCALL1(int, chdir, const char*, path)
+{
+ struct v_dnode* dnode;
+ int errno = 0;
+
+ if ((errno = vfs_walk(__current->cwd, path, &dnode, NULL, 0))) {
+ goto done;
+ }
+
+ errno = __vfs_do_chdir(dnode);
+
+done:
+ return DO_STATUS(errno);
+}
+
+__DEFINE_LXSYSCALL1(int, fchdir, int, fd)
+{
+ struct v_fd* fd_s;
+ int errno = 0;
+
+ if ((errno = __vfs_getfd(fd, &fd_s))) {
+ goto done;
+ }
+
+ errno = __vfs_do_chdir(fd_s->file->dnode);
+
+done:
+ return DO_STATUS(errno);
+}
+
+__DEFINE_LXSYSCALL2(char*, getcwd, char*, buf, size_t, size)
+{
+ int errno = 0;
+ char* ret_ptr = 0;
+ if (size < 2) {
+ errno = ERANGE;
+ goto done;
+ }
+
+ if (!__current->cwd) {
+ *buf = PATH_DELIM;
+ goto done;
+ }
+
+ size_t len = vfs_get_path(__current->cwd, buf, size, 0);
+ if (len == size) {
+ errno = ERANGE;
+ goto done;
+ }
+
+ buf[len + 1] = '\0';
+
+ ret_ptr = buf;
+
+done:
+ __current->k_status = errno;
+ return ret_ptr;