From af27dc0cf7c1f56ece30a2089da41a1cb3d9d7e3 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Wed, 29 Jun 2005 19:28:26 +0000 Subject: [PATCH] Added fchdir() system call, with corresponding manpage, Changelog and system include modifications. --- include/minix/callnr.h | 3 ++- include/unistd.h | 1 + lib/posix/_chdir.c | 10 ++++++++++ man/man2/chdir.2 | 6 +++++- servers/fs/proto.h | 1 + servers/fs/stadir.c | 29 ++++++++++++++++++++++++++--- servers/fs/table.c | 1 + servers/pm/table.c | 1 + 8 files changed, 47 insertions(+), 5 deletions(-) diff --git a/include/minix/callnr.h b/include/minix/callnr.h index 45249511d..1ed0d6b49 100755 --- a/include/minix/callnr.h +++ b/include/minix/callnr.h @@ -1,4 +1,4 @@ -#define NCALLS 86 /* number of system calls allowed */ +#define NCALLS 87 /* number of system calls allowed */ #define EXIT 1 #define FORK 2 @@ -74,3 +74,4 @@ #define ALLOCMEM 83 /* to PM */ #define FREEMEM 84 /* to PM */ #define SELECT 85 /* to FS */ +#define FCHDIR 86 /* to FS */ diff --git a/include/unistd.h b/include/unistd.h index ab62354ad..d23249c0b 100755 --- a/include/unistd.h +++ b/include/unistd.h @@ -85,6 +85,7 @@ _PROTOTYPE( void _exit, (int _status) ); _PROTOTYPE( int access, (const char *_path, int _amode) ); _PROTOTYPE( unsigned int alarm, (unsigned int _seconds) ); _PROTOTYPE( int chdir, (const char *_path) ); +_PROTOTYPE( int fchdir, (int fd) ); _PROTOTYPE( int chown, (const char *_path, _mnx_Uid_t _owner, _mnx_Gid_t _group) ); _PROTOTYPE( int close, (int _fd) ); _PROTOTYPE( char *ctermid, (char *_s) ); diff --git a/lib/posix/_chdir.c b/lib/posix/_chdir.c index 566cde1e8..34c177a6b 100755 --- a/lib/posix/_chdir.c +++ b/lib/posix/_chdir.c @@ -10,3 +10,13 @@ _CONST char *name; _loadname(name, &m); return(_syscall(FS, CHDIR, &m)); } + +PUBLIC int fchdir(fd) +int fd; +{ + message m; + + m.m1_i1 = fd; + return(_syscall(FS, FCHDIR, &m)); +} + diff --git a/man/man2/chdir.2 b/man/man2/chdir.2 index d7b180a7e..b47fa672b 100644 --- a/man/man2/chdir.2 +++ b/man/man2/chdir.2 @@ -7,18 +7,22 @@ .TH CHDIR 2 "August 26, 1985" .UC 4 .SH NAME -chdir \- change current working directory +chdir, fchdir \- change current working directory .SH SYNOPSIS .nf .ft B #include int chdir(const char *\fIpath\fP) +int fchdir(int \fIfd\fP) .ft R .fi .SH DESCRIPTION .I Path is the pathname of a directory. +.I Fd +is the file descriptor of a directory. + .B Chdir causes this directory to become the current working directory, diff --git a/servers/fs/proto.h b/servers/fs/proto.h index ac6248f3c..915501e5f 100644 --- a/servers/fs/proto.h +++ b/servers/fs/proto.h @@ -142,6 +142,7 @@ _PROTOTYPE( zone_t rd_indir, (struct buf *bp, int index) ); /* stadir.c */ _PROTOTYPE( int do_chdir, (void) ); +_PROTOTYPE( int do_fchdir, (void) ); _PROTOTYPE( int do_chroot, (void) ); _PROTOTYPE( int do_fstat, (void) ); _PROTOTYPE( int do_stat, (void) ); diff --git a/servers/fs/stadir.c b/servers/fs/stadir.c index bb029ed69..dbc2f6d14 100644 --- a/servers/fs/stadir.c +++ b/servers/fs/stadir.c @@ -20,9 +20,24 @@ #include "super.h" FORWARD _PROTOTYPE( int change, (struct inode **iip, char *name_ptr, int len)); +FORWARD _PROTOTYPE( int change_into, (struct inode **iip, struct inode *ip)); FORWARD _PROTOTYPE( int stat_inode, (struct inode *rip, struct filp *fil_ptr, char *user_addr) ); +/*===========================================================================* + * do_fchdir * + *===========================================================================*/ +PUBLIC int do_fchdir() +{ + /* Change directory on already-opened fd. */ + struct filp *rfilp; + + /* Is the file descriptor valid? */ + if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code); + + return change_into(&fp->fp_workdir, rfilp->filp_ino); +} + /*===========================================================================* * do_chdir * *===========================================================================*/ @@ -86,13 +101,22 @@ char *name_ptr; /* pointer to the directory name to change to */ int len; /* length of the directory name string */ { /* Do the actual work for chdir() and chroot(). */ - struct inode *rip; - register int r; /* Try to open the new directory. */ if (fetch_name(name_ptr, len, M3) != OK) return(err_code); if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code); + return change_into(iip, rip); +} + +/*===========================================================================* + * change_into * + *===========================================================================*/ +PRIVATE int change_into(iip, rip) +struct inode **iip; /* pointer to the inode pointer for the dir */ +struct inode *rip; /* this is what the inode has to become */ +{ + register int r; /* It must be a directory and also be searchable. */ if ( (rip->i_mode & I_TYPE) != I_DIRECTORY) @@ -112,7 +136,6 @@ int len; /* length of the directory name string */ return(OK); } - /*===========================================================================* * do_stat * *===========================================================================*/ diff --git a/servers/fs/table.c b/servers/fs/table.c index 5505bda0a..9e9c463af 100644 --- a/servers/fs/table.c +++ b/servers/fs/table.c @@ -103,6 +103,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = { no_sys, /* 83 = memalloc */ no_sys, /* 84 = memfree */ do_select, /* 85 = select */ + do_fchdir, /* 86 = fchdir */ }; /* This should not fail with "array size is negative": */ extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1]; diff --git a/servers/pm/table.c b/servers/pm/table.c index 8bb49cf58..3adec3153 100644 --- a/servers/pm/table.c +++ b/servers/pm/table.c @@ -102,6 +102,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = { do_allocmem, /* 83 = memalloc */ do_freemem, /* 84 = memfree */ no_sys, /* 85 = select */ + no_sys, /* 86 = fchdir */ }; /* This should not fail with "array size is negative": */ extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];