summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-09-11 10:34:02 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-09-12 15:31:12 +0200
commitb6657c395747eedba02409388780ad5f05581322 (patch)
tree103bebd674a55b80248959552b3d40272cc14346 /cpukit/libcsupport
parentdosfs: Correct handling of iconv() return value (diff)
downloadrtems-b6657c395747eedba02409388780ad5f05581322.tar.bz2
Filesystem: Add and use rtems_filesystem_chmod()
Implement POSIX requirements in the high-level file system layer.
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r--cpukit/libcsupport/include/rtems/libio_.h5
-rw-r--r--cpukit/libcsupport/src/chmod.c2
-rw-r--r--cpukit/libcsupport/src/fchmod.c49
3 files changed, 47 insertions, 9 deletions
diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
index 55156c0fa8..4a0623eea0 100644
--- a/cpukit/libcsupport/include/rtems/libio_.h
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -566,6 +566,11 @@ int rtems_filesystem_mknod(
int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
+int rtems_filesystem_chmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
int rtems_filesystem_chown(
const char *path,
uid_t owner,
diff --git a/cpukit/libcsupport/src/chmod.c b/cpukit/libcsupport/src/chmod.c
index 8b91b60eae..a8785d40d3 100644
--- a/cpukit/libcsupport/src/chmod.c
+++ b/cpukit/libcsupport/src/chmod.c
@@ -33,7 +33,7 @@ int chmod( const char *path, mode_t mode )
const rtems_filesystem_location_info_t *currentloc =
rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
- rv = (*currentloc->mt_entry->ops->fchmod_h)( currentloc, mode );
+ rv = rtems_filesystem_chmod( currentloc, mode );
rtems_filesystem_eval_path_cleanup( &ctx );
diff --git a/cpukit/libcsupport/src/fchmod.c b/cpukit/libcsupport/src/fchmod.c
index 94e82647fc..b8f4d333fb 100644
--- a/cpukit/libcsupport/src/fchmod.c
+++ b/cpukit/libcsupport/src/fchmod.c
@@ -22,6 +22,42 @@
#include <rtems/libio_.h>
+int rtems_filesystem_chmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+)
+{
+ const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
+ int rv;
+
+ if ( mt_entry->writeable || rtems_filesystem_location_is_null( loc ) ) {
+ struct stat st;
+
+ memset( &st, 0, sizeof(st) );
+
+ rv = (*loc->handlers->fstat_h)( loc, &st );
+ if ( rv == 0 ) {
+ uid_t uid = geteuid();
+
+ if ( uid == 0 || st.st_uid == uid ) {
+ mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX;
+
+ mode = (st.st_mode & ~mask) | (mode & mask);
+
+ rv = (*mt_entry->ops->fchmod_h)( loc, mode );
+ } else {
+ errno = EPERM;
+ rv = -1;
+ }
+ }
+ } else {
+ errno = EROFS;
+ rv = -1;
+ }
+
+ return rv;
+}
+
/**
* POSIX 1003.1b 5.6.4 - Change File Modes
*/
@@ -34,14 +70,11 @@ int fchmod( int fd, mode_t mode )
iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop);
- if (iop->pathinfo.mt_entry->writeable) {
- rtems_filesystem_instance_lock( &iop->pathinfo );
- rv = (*iop->pathinfo.mt_entry->ops->fchmod_h)( &iop->pathinfo, mode );
- rtems_filesystem_instance_unlock( &iop->pathinfo );
- } else {
- errno = EROFS;
- rv = -1;
- }
+ rtems_filesystem_instance_lock( &iop->pathinfo );
+
+ rv = rtems_filesystem_chmod( &iop->pathinfo, mode );
+
+ rtems_filesystem_instance_unlock( &iop->pathinfo );
return rv;
}