summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerick Rethans <derick@php.net>2006-03-05 18:57:54 +0000
committerDerick Rethans <derick@php.net>2006-03-05 18:57:54 +0000
commitf87e7b8babbe000f6201986b8735c6f233824df8 (patch)
treeb70f61a4088a3381a803cbeb3009d4dc2184c3aa
parent7d7304541580bac79045299196a75ab50e94243d (diff)
downloadphp-git-f87e7b8babbe000f6201986b8735c6f233824df8.tar.gz
- Added lchown() and lchgrp() to change user/group ownership of symlinks.
-rw-r--r--NEWS2
-rw-r--r--TSRM/tsrm_virtual_cwd.c12
-rw-r--r--TSRM/tsrm_virtual_cwd.h6
-rw-r--r--configure.in1
-rw-r--r--ext/standard/basic_functions.c2
-rw-r--r--ext/standard/filestat.c76
-rw-r--r--ext/standard/php_filestat.h9
7 files changed, 89 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index 392a66df42..5da6aff0e8 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,8 @@ PHP NEWS
on error.
- Changed get_headers() to retrieve headers also from non-200 responses. (Ilia)
- Changed get_headers() to use the default context. (Ilia)
+- Added lchown() and lchgrp() to change user/group ownership of symlinks.
+ (Derick)
- Added support for exif date format in strtotime(). (Derick)
- Added a check for special characters in the session name. (Ilia)
- Added "consumed" stream filter. (Marcus)
diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c
index a7ce9d29c4..59a6b81d1d 100644
--- a/TSRM/tsrm_virtual_cwd.c
+++ b/TSRM/tsrm_virtual_cwd.c
@@ -765,7 +765,7 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC)
}
#if !defined(TSRM_WIN32) && !defined(NETWARE)
-CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC)
+CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC)
{
cwd_state new_state;
int ret;
@@ -773,7 +773,15 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL, 0);
- ret = chown(new_state.cwd, owner, group);
+ if (link) {
+#if HAVE_LCHOWN
+ ret = lchown(new_state.cwd, owner, group);
+#else
+ ret = -1;
+#endif
+ } else {
+ ret = chown(new_state.cwd, owner, group);
+ }
CWD_STATE_FREE(&new_state);
return ret;
diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h
index 9c1b9d2f0a..5ad435d274 100644
--- a/TSRM/tsrm_virtual_cwd.h
+++ b/TSRM/tsrm_virtual_cwd.h
@@ -175,7 +175,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC);
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
#if !defined(TSRM_WIN32) && !defined(NETWARE)
-CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC);
+CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC);
#endif
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);
@@ -242,7 +242,8 @@ extern virtual_cwd_globals cwd_globals;
#endif
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
-#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group TSRMLS_CC)
+#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group, 0 TSRMLS_CC)
+#define VCWD_LCHOWN(path, owner, group) virtual_chown(path, owner, group, 1 TSRMLS_CC)
#endif
#else
@@ -285,6 +286,7 @@ extern virtual_cwd_globals cwd_globals;
#define VCWD_CHMOD(path, mode) chmod(path, mode)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
+#define VCWD_LCHOWN(path, owner, group) lchown(path, owner, group)
#endif
#endif
diff --git a/configure.in b/configure.in
index 569a6362ec..fe800735bc 100644
--- a/configure.in
+++ b/configure.in
@@ -483,6 +483,7 @@ isascii \
link \
localtime_r \
lockf \
+lchown \
lrand48 \
memcpy \
memmove \
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index bcccc61c31..479af7e931 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -698,8 +698,6 @@ zend_function_entry basic_functions[] = {
#endif
#if HAVE_LCHOWN
PHP_FE(lchown, NULL)
-#endif
-#if HAVE_LCHOWN
PHP_FE(lchgrp, NULL)
#endif
PHP_FE(chmod, NULL)
diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c
index 007305de07..5229252821 100644
--- a/ext/standard/filestat.c
+++ b/ext/standard/filestat.c
@@ -323,12 +323,9 @@ PHP_FUNCTION(disk_free_space)
}
/* }}} */
-/* {{{ proto bool chgrp(string filename, mixed group)
- Change file group */
-#ifndef NETWARE
-PHP_FUNCTION(chgrp)
+
+static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp)
{
-#if !defined(WINDOWS)
zval **filename, **group;
gid_t gid;
struct group *gr=NULL;
@@ -360,25 +357,48 @@ PHP_FUNCTION(chgrp)
RETURN_FALSE;
}
- ret = VCWD_CHOWN(Z_STRVAL_PP(filename), -1, gid);
+ if (do_lchgrp) {
+ ret = VCWD_LCHOWN(Z_STRVAL_PP(filename), -1, gid);
+ } else {
+ ret = VCWD_CHOWN(Z_STRVAL_PP(filename), -1, gid);
+ }
if (ret == -1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
RETURN_FALSE;
}
RETURN_TRUE;
+}
+
+#ifndef NETWARE
+/* {{{ proto bool chgrp(string filename, mixed group)
+ Change file group */
+PHP_FUNCTION(chgrp)
+{
+#if !defined(WINDOWS)
+ php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
#else
RETURN_FALSE;
#endif
}
+/* }}} */
+
+/* {{{ proto bool lchgrp(string filename, mixed group)
+ Change symlink group */
+#if HAVE_LCHOWN
+PHP_FUNCTION(lchgrp)
+{
+# if !defined(WINDOWS)
+ php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+# else
+ RETURN_FALSE;
+# endif
+}
#endif
/* }}} */
+#endif
-/* {{{ proto bool chown (string filename, mixed user)
- Change file owner */
-#ifndef NETWARE
-PHP_FUNCTION(chown)
+static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown)
{
-#if !defined(WINDOWS)
zval **filename, **user;
int ret;
uid_t uid;
@@ -410,16 +430,46 @@ PHP_FUNCTION(chown)
RETURN_FALSE;
}
- ret = VCWD_CHOWN(Z_STRVAL_PP(filename), uid, -1);
+ if (do_lchown) {
+ ret = VCWD_LCHOWN(Z_STRVAL_PP(filename), uid, -1);
+ } else {
+ ret = VCWD_CHOWN(Z_STRVAL_PP(filename), uid, -1);
+ }
if (ret == -1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
RETURN_FALSE;
}
+}
+
+#ifndef NETWARE
+/* {{{ proto bool chown (string filename, mixed user)
+ Change file owner */
+PHP_FUNCTION(chown)
+{
+#if !defined(WINDOWS)
+ RETVAL_TRUE;
+ php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+#else
+ RETURN_FALSE;
#endif
- RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool chown (string filename, mixed user)
+ Change file owner */
+#if HAVE_LCHOWN
+PHP_FUNCTION(lchown)
+{
+# if !defined(WINDOWS)
+ RETVAL_TRUE;
+ php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+# else
+ RETURN_FALSE;
+# endif
}
#endif
/* }}} */
+#endif
/* {{{ proto bool chmod(string filename, int mode)
Change file mode */
diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h
index 66d690a5d0..4c18392d06 100644
--- a/ext/standard/php_filestat.h
+++ b/ext/standard/php_filestat.h
@@ -47,9 +47,18 @@ PHP_FUNCTION(disk_total_space);
PHP_FUNCTION(disk_free_space);
PHP_FUNCTION(chown);
PHP_FUNCTION(chgrp);
+#if HAVE_LCHOWN
+PHP_FUNCTION(lchown);
+#endif
+#if HAVE_LCHOWN
+PHP_FUNCTION(lchgrp);
+#endif
PHP_FUNCTION(chmod);
#if HAVE_UTIME
PHP_FUNCTION(touch);
+# if HAVE_LTOUCH
+PHP_FUNCTION(ltouch);
+# endif
#endif
PHP_FUNCTION(clearstatcache);