Date: Thu, 20 Feb 2003 18:46:54 +0000 From: "Richard Dawe" Sender: rich AT phekda DOT freeserve DOT co DOT uk To: djgpp-workers AT delorie DOT com X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: FSEXT hooks for chmod, chown, revision 2 [PATCH] Message-Id: Reply-To: djgpp-workers AT delorie DOT com Hello. It occurred to me after sending the original patch that chown on /dev/zero and /dev/full should probably behave like chown does for other files. Below is a patch with this change. I've also split out the code for chmod in the /dev/zero and /dev/full FSEXT. The test cases for /dev/zero and /dev/full were updated appropriately. OK to commit? Thanks, bye, Rich =] Index: include/sys/fsext.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/sys/fsext.h,v retrieving revision 1.8 diff -p -c -3 -r1.8 fsext.h *** include/sys/fsext.h 4 Feb 2003 20:25:29 -0000 1.8 --- include/sys/fsext.h 20 Feb 2003 18:40:32 -0000 *************** typedef enum { *** 43,48 **** --- 43,50 ---- __FSEXT_llseek, __FSEXT_readlink, __FSEXT_symlink, + __FSEXT_chmod, + __FSEXT_chown, __FSEXT_fchown } __FSEXT_Fnumber; Index: src/libc/fsext/fsext.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/fsext/fsext.txh,v retrieving revision 1.17 diff -p -c -3 -r1.17 fsext.txh *** src/libc/fsext/fsext.txh 29 Jan 2003 12:51:07 -0000 1.17 --- src/libc/fsext/fsext.txh 20 Feb 2003 18:40:34 -0000 *************** symlinks in other than DJGPP symlink fil *** 167,172 **** --- 167,186 ---- The source and destination file names are passed to the handler unchanged. + @item __FSEXT_chmod + + A file chmod handler (@pxref{chmod}). This is called when + the permissions are to be changed for a file. + + The file name passed to the handler will have all its symlinks resolved. + + @item __FSEXT_chown + + A file chown handler (@pxref{chown}). This is called when + the ownership is to be changed for a file. + + The file name passed to the handler will have all its symlinks resolved. + @item __FSEXT_fchown A file fchown handler (@pxref{fchown}). This is called when Index: src/libc/posix/sys/stat/chmod.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/chmod.c,v retrieving revision 1.2 diff -p -c -3 -r1.2 chmod.c *** src/libc/posix/sys/stat/chmod.c 22 Aug 2000 18:40:19 -0000 1.2 --- src/libc/posix/sys/stat/chmod.c 20 Feb 2003 18:40:41 -0000 *************** *** 1,3 **** --- 1,4 ---- + /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include *************** *** 5,10 **** --- 6,13 ---- #include #include #include + #include + #include int chmod(const char *filename, int pmode) *************** chmod(const char *filename, int pmode) *** 12,20 **** --- 15,29 ---- int dmode; char real_name[FILENAME_MAX]; int attr; + int rv; if (!__solve_symlinks(filename, real_name)) return -1; + + /* See if a file system extension has a hook for this file. */ + if (__FSEXT_call_open_handlers_wrapper(__FSEXT_chmod, &rv, + real_name, pmode)) + return rv; attr = _chmod(real_name, 0, 0); Index: src/libc/posix/sys/stat/chmod.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/chmod.txh,v retrieving revision 1.3 diff -p -c -3 -r1.3 chmod.txh *** src/libc/posix/sys/stat/chmod.txh 29 Jan 2003 12:51:41 -0000 1.3 --- src/libc/posix/sys/stat/chmod.txh 20 Feb 2003 18:40:41 -0000 *************** Make the file writable *** 28,33 **** --- 28,36 ---- Other @code{S_I*} values could be included, but they will be ignored. + This function can be hooked by File System Extensions + (@pxref{File System Extensions}). + @subheading Return Value Zero if the file exists and the mode was changed, else nonzero. Index: src/libc/posix/unistd/chown.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/chown.c,v retrieving revision 1.2 diff -p -c -3 -r1.2 chown.c *** src/libc/posix/unistd/chown.c 28 Jun 2000 18:37:17 -0000 1.2 --- src/libc/posix/unistd/chown.c 20 Feb 2003 18:40:56 -0000 *************** *** 1,21 **** /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include #include /* MS-DOS couldn't care less about file ownerships, so we could always succeed. At least fail for non-existent files ! and for devices. */ int ! chown(const char *path, uid_t owner __attribute__((__unused__)), ! gid_t group __attribute__((__unused__))) { if (access(path, F_OK)) /* non-existent file */ { errno = ENOENT; return -1; } return 0; } --- 1,37 ---- + /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include + #include #include #include + #include + #include + #include /* MS-DOS couldn't care less about file ownerships, so we could always succeed. At least fail for non-existent files ! and for devices. Let FSEXTs handle it, if they want. */ int ! chown(const char *path, uid_t owner, gid_t group) { + char real_name[FILENAME_MAX]; + int rv; + if (access(path, F_OK)) /* non-existent file */ { errno = ENOENT; return -1; } + + if (!__solve_symlinks(path, real_name)) + return -1; + + /* See if a file system extension has a hook for this file. */ + if (__FSEXT_call_open_handlers_wrapper(__FSEXT_chown, &rv, + real_name, owner, group)) + return rv; + return 0; } Index: src/libc/posix/unistd/chown.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/chown.txh,v retrieving revision 1.5 diff -p -c -3 -r1.5 chown.txh *** src/libc/posix/unistd/chown.txh 29 Jan 2003 12:51:41 -0000 1.5 --- src/libc/posix/unistd/chown.txh 20 Feb 2003 18:40:56 -0000 *************** int chown(const char *file, int owner, i *** 13,19 **** This function changes the ownership of the open file specified by @var{file} to the user ID @var{owner} and group ID @var{group}. ! This function does nothing under MS-DOS. @subheading Return Value --- 13,20 ---- This function changes the ownership of the open file specified by @var{file} to the user ID @var{owner} and group ID @var{group}. ! This function does nothing under MS-DOS. This function can ! be hooked by File System Extensions (@pxref{File System Extensions}). @subheading Return Value Index: src/libc/fsext/fse_zero.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/fsext/fse_zero.c,v retrieving revision 1.3 diff -p -c -3 -r1.3 fse_zero.c *** src/libc/fsext/fse_zero.c 10 Jan 2003 19:07:12 -0000 1.3 --- src/libc/fsext/fse_zero.c 20 Feb 2003 18:41:08 -0000 *************** dev_fsext (__FSEXT_Fnumber n, int *rv, v *** 184,190 **** char *new_filename = NULL; int open_mode = 0; int perm = 0; ! mode_t creat_mode = 0; void *buf = NULL; size_t buflen = 0; off_t offset = 0; --- 184,190 ---- char *new_filename = NULL; int open_mode = 0; int perm = 0; ! mode_t mode = 0; void *buf = NULL; size_t buflen = 0; off_t offset = 0; *************** dev_fsext (__FSEXT_Fnumber n, int *rv, v *** 278,285 **** break; case __FSEXT_creat: ! filename = va_arg(args, char *); ! creat_mode = va_arg(args, mode_t); /* Check the filename */ if ( !match_dev_path(filename, DEV_ZERO_PATH) --- 278,285 ---- break; case __FSEXT_creat: ! filename = va_arg(args, char *); ! mode = va_arg(args, mode_t); /* Check the filename */ if ( !match_dev_path(filename, DEV_ZERO_PATH) *************** dev_fsext (__FSEXT_Fnumber n, int *rv, v *** 549,554 **** --- 549,603 ---- } /* Seek is meaningless */ + *rv = 0; + break; + + case __FSEXT_chmod: + filename = va_arg(args, char *); + mode = va_arg(args, mode_t); + + /* Check the filename */ + if ( !match_dev_path(filename, DEV_ZERO_PATH) + && !match_dev_path(filename, DEV_FULL_PATH)) + break; + + /* Check whether the zero/full device has been installed. */ + if (match_dev_path(filename, DEV_ZERO_PATH) && !dev_zero_installed) + break; + + if (match_dev_path(filename, DEV_FULL_PATH) && !dev_full_installed) + break; + + /* This must be emulated, since the FSEXT has been called. */ + emul = 1; + + /* The zero device cannot have its mode changed. */ + errno = EPERM; + *rv = -1; + break; + + case __FSEXT_chown: + filename = va_arg(args, char *); + owner = va_arg(args, uid_t); + group = va_arg(args, gid_t); + + /* Check the filename */ + if ( !match_dev_path(filename, DEV_ZERO_PATH) + && !match_dev_path(filename, DEV_FULL_PATH)) + break; + + /* Check whether the zero/full device has been installed. */ + if (match_dev_path(filename, DEV_ZERO_PATH) && !dev_zero_installed) + break; + + if (match_dev_path(filename, DEV_FULL_PATH) && !dev_full_installed) + break; + + /* This must be emulated, since the FSEXT has been called. */ + emul = 1; + + /* Behave like chown() does on a regular file - succeed whatever + * the uid, gid are. */ *rv = 0; break; Index: src/docs/kb/wc204.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v retrieving revision 1.138 diff -p -c -3 -r1.138 wc204.txi *** src/docs/kb/wc204.txi 4 Feb 2003 20:19:22 -0000 1.138 --- src/docs/kb/wc204.txi 20 Feb 2003 18:41:18 -0000 *************** The constants @code{HUGE_VALF} and @code *** 860,862 **** --- 860,866 ---- The error code @code{EILSEQ} was added --- @code{errno} may be assigned it. @code{perror} and @code{strerror} were updated to display/return an error message for @code{EILSEQ}. + + @cindex File System Extensions, and @code{chmod} + @cindex File System Extensions, and @code{chown} + @code{chmod} and @code{chown} can now be hooked by File System Extensions. Index: tests/libc/fsext/tzero.c =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/fsext/tzero.c,v retrieving revision 1.2 diff -p -c -3 -r1.2 tzero.c *** tests/libc/fsext/tzero.c 14 Jun 2002 09:11:07 -0000 1.2 --- tests/libc/fsext/tzero.c 20 Feb 2003 18:41:25 -0000 *************** *** 1,3 **** --- 1,4 ---- + /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ *************** main (int argc, char *argv[]) *** 372,377 **** --- 373,399 ---- } assert(errno == EPERM); + + /* - Check chmod() fails - */ + n = chmod(DEV_ZERO_PATH, S_IWUSR); + if (n >= 0) { + fprintf(stderr, + "chmod() succeeded in changing permissions of %s -" + "it should fail\n", + DEV_ZERO_PATH); + return(EXIT_FAILURE); + } + + assert(errno == EPERM); + + /* - Check chown() succeeds - */ + n = chown(DEV_ZERO_PATH, 2 * getuid(), 2 * getgid()); + if (n < 0) { + fprintf(stderr, + "chown() failed to change ownership of %s\n", + DEV_ZERO_PATH); + return(EXIT_FAILURE); + } /* - Check lseek() - */ fd = open(DEV_ZERO_PATH, O_RDWR);