Skip to content

Commit

Permalink
Add new syscall: getcwd
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
penberg committed Jan 3, 2012
1 parent e7f42dc commit 017d64c
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 1 deletion.
5 changes: 5 additions & 0 deletions fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
19 changes: 19 additions & 0 deletions fs/minix/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down
13 changes: 13 additions & 0 deletions fs/sys.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <inode.h>
#include <print.h>
#include <file.h>
#include <slab.h>
#include <task.h>
#include <fs.h>

Expand Down Expand Up @@ -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);
}
2 changes: 2 additions & 0 deletions include/inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */
4 changes: 3 additions & 1 deletion include/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
1 change: 1 addition & 0 deletions kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions user/include/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
1 change: 1 addition & 0 deletions user/include/ulib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions user/libc/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
5 changes: 5 additions & 0 deletions user/libc/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.