Permalink
Browse files

Add new syscall: getcwd

This patch adds a new getcwd() syscall that returns the current working
directory to userspace. The implementation is lame because current directory is
tied to an inode instead of a dentry, and there's no way to look up the full
dentry chain.

But whatever, it's a decent start.

Signed-off-by: Pekka Enberg <penberg@kernel.org>
  • Loading branch information...
penberg committed Jan 3, 2012
1 parent e7f42dc commit 017d64cb591cafdab70bd4d5d75e7c23ec4441e1
Showing with 59 additions and 1 deletion.
  1. +5 −0 fs/inode.c
  2. +19 −0 fs/minix/inode.c
  3. +13 −0 fs/sys.c
  4. +2 −0 include/inode.h
  5. +3 −1 include/syscall.h
  6. +1 −0 kernel/syscall.c
  7. +2 −0 user/include/syscall.h
  8. +1 −0 user/include/ulib.h
  9. +8 −0 user/libc/file.c
  10. +5 −0 user/libc/syscall.c
View
@@ -169,3 +169,8 @@ int inode_rm(char *path)
}
return r;
}
+
+int inode_get_pathname(struct inode *inode, char *pathname, size_t len)
+{
+ return inode->i_ops->get_pathname(inode, pathname, len);
+}
View
@@ -481,6 +481,24 @@ void minix_inode_stat(struct inode *inode, struct file_stat *stat)
stat->link = i2mdi(inode)->i_nlinks;
}
+int minix_get_pathname(struct inode *inode, char *pathname, size_t len)
+{
+ struct minix_dentry *de;
+
+ if (len < MINIX_NAME_LEN + 1)
+ return -1;
+
+ de = minix_lookup_dentry(inode, ".", 1, NULL);
+ if (!de)
+ return -1;
+
+ strncpy(pathname, de->d_name, MINIX_NAME_LEN);
+
+ pathname[MINIX_NAME_LEN] = '\0';
+
+ return 0;
+}
+
void minix_inode_truncate(struct inode *inode)
{
bmap_put_blocks(inode);
@@ -528,6 +546,7 @@ static struct inode_operations minix_dir_iops = {
.create = minix_inode_create,
.rm = minix_inode_rm,
.stat = minix_inode_stat,
+ .get_pathname = minix_get_pathname,
};
/* regular file operations */
View
@@ -1,5 +1,7 @@
+#include <inode.h>
#include <print.h>
#include <file.h>
+#include <slab.h>
#include <task.h>
#include <fs.h>
@@ -201,3 +203,14 @@ int sys_truncate(int fd)
put_file(file);
return r;
}
+
+int sys_getcwd(char *buf, size_t size)
+{
+ struct inode *inode;
+
+ inode = ctask->fs.current_dir;
+ if (!inode)
+ return -1;
+
+ return inode_get_pathname(inode, buf, size);
+}
View
@@ -23,6 +23,7 @@ struct inode_operations {
int (*rm)(struct inode *, char *, int);
void (*stat)(struct inode *, struct file_stat *);
void (*truncate)(struct inode *);
+ int (*get_pathname)(struct inode *, char *, size_t);
};
struct inode {
@@ -58,5 +59,6 @@ extern int inode_rmdir(char *path);
extern int inode_rm(char *path);
extern struct inode *inode_sub_lookup_put(struct inode *, char *, int);
extern int inode_truncate(struct inode *);
+extern int inode_get_pathname(struct inode *, char *, size_t);
#endif /* inode.h */
View
@@ -30,7 +30,8 @@ typedef u32 (*syscall_t)(u32, u32, u32, u32, u32);
#define SYS_rmdir 20
#define SYS_rm 21
#define SYS_truncate 22
-#define SYS_CALL_MAX 22
+#define SYS_getcwd 23
+#define SYS_CALL_MAX 23
extern int sys_puts(char *);
extern int sys_gets(char *, int);
@@ -54,5 +55,6 @@ extern void sys_sync(void);
extern int sys_rmdir(char *);
extern int sys_rm(char *);
extern int sys_truncate(int);
+extern int sys_getcwd(char *buf, size_t size);
#endif /* syscall.h */
View
@@ -27,6 +27,7 @@ static syscall_t sys_call_table[SYS_CALL_MAX + 1] = {
__sys_call_entry(rmdir),
__sys_call_entry(rm),
__sys_call_entry(truncate),
+ __sys_call_entry(getcwd),
};
void do_sys_call(struct regs *reg)
View
@@ -30,6 +30,7 @@ struct dir_stat;
#define SYS_rmdir 20
#define SYS_rm 21
#define SYS_truncate 22
+#define SYS_getcwd 23
extern int usys_puts(char *);
extern int usys_gets(char *, int);
@@ -53,5 +54,6 @@ extern void usys_sync(void);
extern int usys_rmdir(char *);
extern int usys_rm(char *);
extern int usys_truncate(int);
+extern int usys_getcwd(char *buf, size_t size);
#endif /* syscall.h */
View
@@ -30,6 +30,7 @@ extern int rmdir(char *);
extern int rm(char *);
extern void sync(void);
extern int truncate(int);
+extern char *getcwd(char *buf, size_t size);
#define S_IFMT 00170000
#define S_IFSOCK 0140000
View
@@ -95,3 +95,11 @@ int truncate(int fd)
{
return usys_truncate(fd);
}
+
+char *getcwd(char *buf, size_t size)
+{
+ if (usys_getcwd(buf, size))
+ return NULL;
+
+ return buf;
+}
View
@@ -128,3 +128,8 @@ int usys_truncate(int fd)
{
return usyscall(SYS_truncate, (u32)fd, 0, 0, 0, 0);
}
+
+int usys_getcwd(char *buf, size_t size)
+{
+ return usyscall(SYS_getcwd, (u32)buf, (u32)size, 0, 0, 0);
+}

0 comments on commit 017d64c

Please sign in to comment.