10 * Convert a relative pathname to an absolute pathname
11 * In the future this might also resolve symlinks...
13 void pm_realpath(com32sys_t
*regs
)
15 const char *src
= MK_PTR(regs
->ds
, regs
->esi
.w
[0]);
16 char *dst
= MK_PTR(regs
->es
, regs
->edi
.w
[0]);
18 realpath(dst
, src
, FILENAME_MAX
);
21 static size_t copy_string(char *buf
, size_t ix
, size_t bufsize
, const char *src
)
25 while ((c
= *src
++)) {
37 static size_t generic_inode_to_path(struct inode
*inode
, char *dst
, size_t bufsize
)
41 dprintf("inode %p name %s\n", inode
, inode
->name
);
44 if (!inode
->name
) /* Only the root should have no name */
47 s
= generic_inode_to_path(inode
->parent
, dst
, bufsize
);
49 return s
; /* Error! */
51 s
= copy_string(dst
, s
, bufsize
, "/");
52 s
= copy_string(dst
, s
, bufsize
, inode
->name
);
58 __export
size_t realpath(char *dst
, const char *src
, size_t bufsize
)
64 dprintf("realpath: input: %s\n", src
);
66 if (this_fs
->fs_ops
->realpath
) {
67 s
= this_fs
->fs_ops
->realpath(this_fs
, dst
, src
, bufsize
);
69 rv
= searchdir(src
, O_RDONLY
);
71 dprintf("realpath: searchpath failure\n");
75 file
= handle_to_file(rv
);
76 s
= generic_inode_to_path(file
->inode
, dst
, bufsize
);
78 s
= copy_string(dst
, 0, bufsize
, "/");
83 dprintf("realpath: output: %s\n", dst
);
87 __export
int chdir(const char *src
)
91 char cwd_buf
[CURRENTDIR_MAX
];
94 dprintf("chdir: from %s (inode %p) add %s\n",
95 this_fs
->cwd_name
, this_fs
->cwd
, src
);
97 if (this_fs
->fs_ops
->chdir
)
98 return this_fs
->fs_ops
->chdir(this_fs
, src
);
100 /* Otherwise it is a "conventional filesystem" */
101 rv
= searchdir(src
, O_RDONLY
|O_DIRECTORY
);
105 file
= handle_to_file(rv
);
106 if (file
->inode
->mode
!= DT_DIR
) {
111 put_inode(this_fs
->cwd
);
112 this_fs
->cwd
= get_inode(file
->inode
);
115 /* Save the current working directory */
116 s
= generic_inode_to_path(this_fs
->cwd
, cwd_buf
, CURRENTDIR_MAX
-1);
118 /* Make sure the cwd_name ends in a slash, it's supposed to be a prefix */
119 if (s
< 1 || cwd_buf
[s
-1] != '/')
122 if (s
>= CURRENTDIR_MAX
)
123 s
= CURRENTDIR_MAX
- 1;
126 memcpy(this_fs
->cwd_name
, cwd_buf
, s
);
128 dprintf("chdir: final %s (inode %p)\n",
129 this_fs
->cwd_name
, this_fs
->cwd
);