delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/02/04/17:00:13

Date: Tue, 04 Feb 2003 22:02:04 +0000
From: "Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
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: Implementation of fchmod [PATCH]
Message-Id: <E18gB6p-0000qr-00@phekda.freeserve.co.uk>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Below is an implementation of fchmod. It uses fd_props to get
the filename for the file descriptor, so that we can use chmod
on the file.

One thing I'm not entirely happy is the error code to return, when
we can't find the filename. I chose ENOENT. The only other reasonable
choice I could think of is EPERM. Neither are entirely truthful,
but perhaps applications have been written to expect EPERM?

OK to commit?

Bye, Rich =]

Index: include/sys/stat.h
===================================================================
RCS file: /cvs/djgpp/djgpp/include/sys/stat.h,v
retrieving revision 1.8
diff -p -c -3 -r1.8 stat.h
*** include/sys/stat.h	4 Feb 2003 20:25:54 -0000	1.8
--- include/sys/stat.h	4 Feb 2003 21:55:30 -0000
*************** struct stat {
*** 63,68 ****
--- 63,69 ----
  };
  
  int	chmod(const char *_path, mode_t _mode);
+ int	fchmod(int _fildes, mode_t _mode);
  int	fstat(int _fildes, struct stat *_buf);
  int	mkdir(const char *_path, mode_t _mode);
  int	mkfifo(const char *_path, mode_t _mode);
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	4 Feb 2003 21:55:33 -0000
*************** typedef enum {
*** 43,49 ****
    __FSEXT_llseek,
    __FSEXT_readlink,
    __FSEXT_symlink,
!   __FSEXT_fchown
  } __FSEXT_Fnumber;
  
  /* _ready gets passed a fd and should return a mask of these,
--- 43,50 ----
    __FSEXT_llseek,
    __FSEXT_readlink,
    __FSEXT_symlink,
!   __FSEXT_fchown,
!   __FSEXT_fchmod
  } __FSEXT_Fnumber;
  
  /* _ready gets passed a fd and should return a mask of these,
Index: src/libc/posix/sys/stat/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/makefile,v
retrieving revision 1.4
diff -p -c -3 -r1.4 makefile
*** src/libc/posix/sys/stat/makefile	17 Oct 2002 23:00:25 -0000	1.4
--- src/libc/posix/sys/stat/makefile	4 Feb 2003 21:55:33 -0000
***************
*** 1,9 ****
--- 1,11 ----
+ # Copyright (C) 2003 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
  # Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details
  TOP=../../..
  
  SRC += chmod.c
+ SRC += fchmod.c
  SRC += filelen.c
  SRC += fixpath.c
  SRC += fstat.c
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	4 Feb 2003 21:55:41 -0000
*************** The constants @code{HUGE_VALF} and @code
*** 860,862 ****
--- 860,865 ----
  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}.
+ 
+ @findex fchmod
+ The function @code{fchmod} was added.
Index: tests/libc/posix/sys/stat/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/tests/libc/posix/sys/stat/makefile,v
retrieving revision 1.4
diff -p -c -3 -r1.4 makefile
*** tests/libc/posix/sys/stat/makefile	22 Aug 2000 18:57:32 -0000	1.4
--- tests/libc/posix/sys/stat/makefile	4 Feb 2003 21:55:41 -0000
***************
*** 1,5 ****
--- 1,6 ----
  TOP=../../..
  
+ SRC += t-fchmod.c
  SRC += fixpath.c
  SRC += fstat.c
  SRC += leak.c
*** /dev/null	Tue Feb  4 21:58:08 2003
--- src/libc/posix/sys/stat/fchmod.c	Tue Feb  4 21:37:10 2003
***************
*** 0 ****
--- 1,32 ----
+ /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
+ #include <libc/stubs.h>
+ #include <string.h>
+ #include <sys/stat.h>
+ #include <errno.h>
+ #include <io.h>
+ #include <sys/fsext.h>
+ #include <libc/fsexthlp.h>
+ #include <libc/fd_props.h>
+ 
+ int
+ fchmod (int fd, mode_t mode)
+ {
+   __FSEXT_Function *func     = __FSEXT_get_function(fd);
+   const char       *filename = __get_fd_name(fd);
+   int               rv;
+ 
+   if (   func
+       && __FSEXT_func_wrapper(func, __FSEXT_fchmod, &rv, fd, mode))
+       return(rv);
+ 
+   /* Check that it's a valid file descriptor. */
+   if (_get_dev_info(fd) == -1)
+     return(-1);
+ 
+   if (filename == NULL) {
+     errno = ENOENT;
+     return(-1);
+   }
+ 
+   return(chmod(filename, mode));
+ }
*** /dev/null	Tue Feb  4 21:58:08 2003
--- src/libc/posix/sys/stat/fchmod.txh	Tue Feb  4 21:53:26 2003
***************
*** 0 ****
--- 1,50 ----
+ @node fchmod, file system
+ @findex fchmod
+ @subheading Syntax
+ 
+ @example
+ #include <sys/stat.h>
+ 
+ int fchmod(int fd, mode_t mode);
+ @end example
+ 
+ @subheading Description
+ 
+ This function changes the mode (writable or write-only) of the file
+ opened under the file descriptor @var{fd}.  The value of @var{mode}
+ can be a combination of one or more of the following:
+ 
+ @table @code
+ 
+ @item S_IRUSR
+ 
+ Make the file readable
+ 
+ @item S_IWUSR
+ 
+ Make the file writable
+ 
+ @end table
+ 
+ Other @code{S_I*} values could be included, but they will be ignored
+ for regular files.
+ 
+ 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. 
+ 
+ @subheading Portability
+ 
+ @portability !ansi, posix
+ 
+ @subheading Example
+ 
+ @example
+ int fd;
+ 
+ fd = open("/tmp/dj.dat", O_RDWR);
+ fchmod(fd, S_IWUSR|S_IRUSR);
+ @end example
*** /dev/null	Tue Feb  4 21:58:08 2003
--- tests/libc/posix/sys/stat/t-fchmod.c	Tue Feb  4 21:50:16 2003
***************
*** 0 ****
--- 1,60 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ 
+ const char TEST_FILE[] = "t-fchmod.tst";
+ 
+ static void
+ die (const char *prog_name)
+ {
+   perror(prog_name);
+   puts("FAIL");
+   exit(EXIT_FAILURE);
+ }
+ 
+ int
+ main (int argc, char *argv[])
+ {
+   int fd;
+ 
+   /* Remove the test file, if it exists. */
+   if (!access(TEST_FILE, F_OK) && unlink(TEST_FILE))
+     die(argv[0]);
+ 
+   /* Create the file with read-write permissions. */
+   fd = open(TEST_FILE, O_BINARY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
+   if (fd < 0)
+     die(argv[0]);
+   close(fd);
+ 
+   /* Check the permissions are read-write. */
+   if (access(TEST_FILE, R_OK) || access(TEST_FILE, W_OK))
+     {
+       printf("%s should be readable and writeable!\nFAIL\n", TEST_FILE);
+       return(EXIT_FAILURE);
+     }
+ 
+   /* Re-open the file and change the permissions to read-only. */
+   fd = open(TEST_FILE, O_BINARY, S_IRUSR|S_IWUSR);
+   if (fchmod(fd, S_IRUSR) < 0)
+     die(argv[0]);
+   close(fd);
+ 
+   /* Check the permissions are read-only. */
+   if (access(TEST_FILE, R_OK))
+     {
+       printf("%s should be readable!\nFAIL\n", TEST_FILE);
+       return(EXIT_FAILURE);
+     }
+ 
+   if (!access(TEST_FILE, W_OK))
+     {
+       printf("%s should not be writeable!\nFAIL\n", TEST_FILE);
+       return(EXIT_FAILURE);
+     }
+ 
+   puts("PASS");
+   return(EXIT_SUCCESS);
+ }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019