php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #72986
Patch php-7.0.3-aix-trailing-slash.patch revision 2016-08-31 07:55 UTC by matthieu dot sarter dot external at atos dot net

Patch php-7.0.3-aix-trailing-slash.patch for *Directory/Filesystem functions Bug #72986

Patch version 2016-08-31 07:55 UTC

Return to Bug #72986 | Download this patch
Patch Revisions:

Developer: matthieu.sarter.external@atos.net

diff -Nur php-7.0.3.orig/Zend/zend_virtual_cwd.c php-7.0.3-aix/Zend/zend_virtual_cwd.c
--- php-7.0.3.orig/Zend/zend_virtual_cwd.c	2016-02-02 17:32:20 +0100
+++ php-7.0.3-aix/Zend/zend_virtual_cwd.c	2016-03-11 11:13:59 +0100
@@ -58,6 +58,10 @@
 #include <fsio.h>
 #endif
 
+#ifdef _AIX
+#include <sys/vnode.h>
+#endif
+
 #ifndef HAVE_REALPATH
 #define realpath(x,y) strcpy(y,x)
 #endif
@@ -404,6 +408,104 @@
 /* }}} */
 #endif
 
+#ifdef _AIX
+/*
+The AIX file operations accepts a regular fine name appended with a trailing
+slash.
+To ensure a consistent behavior on Linux and AIX, check if a path with a trailing
+slash is a directory and simulate Linux behavior if not.
+*/
+#define ERROR_IF_FILE_WITH_TRAILING_SLASH(path, retval, set_errno, retval_if_not_exists, errno_if_not_exists) \
+	if (path[strlen(path) - 1] == '/') {\
+		if (access(path, F_OK) == 0) {\
+			struct stat buf;\
+			if (stat(path, &buf) == 0 && buf.st_type != VDIR) {\
+				if (set_errno != -1) {\
+					errno = set_errno;\
+				}\
+				return retval;\
+			}\
+		}\
+		else if (errno_if_not_exists > 0) {\
+			errno = errno_if_not_exists;\
+			return retval_if_not_exists;\
+		}\
+	}
+
+CWD_API int stat_aix(const char *path, struct stat *buf) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, -1, ENOTDIR, 0, 0);
+	return stat(path, buf);
+}
+
+CWD_API int lstat_aix(const char *path, struct stat *buf) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, -1, ENOTDIR, 0, 0);
+	return lstat(path, buf);
+}
+
+CWD_API int rename_aix(const char *oldname, const char *newname) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(oldname, -1, ENOTDIR, 0, 0);
+	return rename(oldname, newname);
+}
+
+CWD_API int access_aix(const char *path, int mode) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, -1, ENOTDIR, 0, 0);
+	return access(path, mode);
+}
+
+CWD_API int unlink_aix(const char *path) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, -1, ENOTDIR, 0, 0);
+	return unlink(path);
+}
+
+CWD_API FILE *fopen_aix(const char *path, const char *type) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, 0, ENOTDIR, NULL, EISDIR);
+	return fopen(path, type);
+}
+
+CWD_API FILE *popen_aix(const char *path, const char *type) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, 0, ENOTDIR, NULL, EISDIR);
+	/*
+	On Linux, popen does not allow r and w simultaneously
+	*/
+	if (strchr(type, 'r') != NULL && strchr(type, 'w') != NULL) {
+		errno = EINVAL;
+		return NULL;
+	}
+	return popen(path, type);
+}
+
+CWD_API int open_aix(const char *path, int flag) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, 0, ENOTDIR, -1, EISDIR);
+	return open(path, flag);
+}
+
+CWD_API int open_mode_aix(const char *path, int flag, mode_t mode) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, 0, ENOTDIR, -1, EISDIR);
+	return open(path, flag, mode);
+}
+
+CWD_API int creat_aix(const char *path, mode_t mode) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, 0, ENOTDIR, -1, EISDIR);
+	return creat(path, mode);
+}
+
+CWD_API int utime_aix(const char *path, const struct utimbuf *times) /* {{{ */
+{
+	ERROR_IF_FILE_WITH_TRAILING_SLASH(path, -1, ENOTDIR, 0, 0);
+	return utime(path, times);
+}
+#endif
+
 static int php_is_dir_ok(const cwd_state *state)  /* {{{ */
 {
 	zend_stat_t buf;
diff -Nur php-7.0.3.orig/Zend/zend_virtual_cwd.h php-7.0.3-aix/Zend/zend_virtual_cwd.h
--- php-7.0.3.orig/Zend/zend_virtual_cwd.h	2016-02-02 17:32:20 +0100
+++ php-7.0.3-aix/Zend/zend_virtual_cwd.h	2016-03-11 11:14:05 +0100
@@ -129,11 +129,31 @@
 #	define CWD_API
 #endif
 
+#ifdef _AIX
+CWD_API int stat_aix(const char *path, struct stat *buf);
+CWD_API int lstat_aix(const char *path, struct stat *buf);
+CWD_API int rename_aix(const char *oldname, const char *newname);
+CWD_API int access_aix(const char *path, int mode);
+CWD_API int unlink_aix(const char *path);
+CWD_API FILE *fopen_aix(const char *path, const char *type);
+CWD_API int open_aix(const char *path, int flag);
+CWD_API int open_mode_aix(const char *path, int flag, mode_t mode);
+CWD_API int creat_aix(const char *path, mode_t mode);
+CWD_API int utime_aix(const char *path, const struct utimbuf *times);
+CWD_API FILE *popen_aix(const char *path, const char *type);
+#endif
+
 #ifdef ZEND_WIN32
 CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat);
 # define php_sys_stat(path, buf) php_sys_stat_ex(path, buf, 0)
 # define php_sys_lstat(path, buf) php_sys_stat_ex(path, buf, 1)
 CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len);
+#elif defined(_AIX)
+# define php_sys_stat(path, buf) stat_aix(path, buf)
+# define php_sys_lstat(path, buf) lstat_aix(path, buf)
+# ifdef HAVE_SYMLINK
+# define php_sys_readlink(link, target, target_len) readlink(link, target, target_len)
+# endif
 #else
 # define php_sys_stat stat
 # define php_sys_lstat lstat
@@ -290,14 +310,23 @@
 #else
 
 #define VCWD_GETCWD(buff, size) getcwd(buff, size)
-#define VCWD_FOPEN(path, mode)  fopen(path, mode)
-#define VCWD_OPEN(path, flags) open(path, flags)
-#define VCWD_OPEN_MODE(path, flags, mode)	open(path, flags, mode)
-#define VCWD_CREAT(path, mode) creat(path, mode)
+#ifdef _AIX
+# define VCWD_FOPEN(path, mode)  fopen_aix(path, mode)
+# define VCWD_OPEN(path, flags) open_aix(path, flags)
+# define VCWD_OPEN_MODE(path, flags, mode)	open_mode_aix(path, flags, mode)
+# define VCWD_CREAT(path, mode) creat_aix(path, mode)
+#else
+# define VCWD_FOPEN(path, mode)  fopen(path, mode)
+# define VCWD_OPEN(path, flags) open(path, flags)
+# define VCWD_OPEN_MODE(path, flags, mode)	open(path, flags, mode)
+# define VCWD_CREAT(path, mode) creat(path, mode)
+#endif
 /* rename on windows will fail if newname already exists.
    MoveFileEx has to be used */
 #if defined(ZEND_WIN32)
 # define VCWD_RENAME(oldname, newname) (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED) == 0 ? -1 : 0)
+#elif defined(_AIX)
+# define VCWD_RENAME(oldname, newname) rename_aix(oldname, newname)
 #else
 # define VCWD_RENAME(oldname, newname) rename(oldname, newname)
 #endif
@@ -305,14 +334,25 @@
 #define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
 #define VCWD_GETWD(buf) getwd(buf)
 #define VCWD_STAT(path, buff) php_sys_stat(path, buff)
-#define VCWD_LSTAT(path, buff) lstat(path, buff)
-#define VCWD_UNLINK(path) unlink(path)
+#if defined(_AIX)
+# define VCWD_LSTAT(path, buf) lstat_aix(path, buf)
+# define VCWD_UNLINK(path) unlink_aix(path)
+#else
+# define VCWD_LSTAT(path, buff) lstat(path, buff)
+# define VCWD_UNLINK(path) unlink(path)
+#endif
 #define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode)
 #define VCWD_RMDIR(pathname) rmdir(pathname)
 #define VCWD_OPENDIR(pathname) opendir(pathname)
-#define VCWD_POPEN(command, type) popen(command, type)
+#ifdef _AIX
+# define VCWD_POPEN(command, type) popen_aix(command, type)
+#else
+# define VCWD_POPEN(command, type) popen(command, type)
+#endif
 #if defined(ZEND_WIN32)
 #define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode)
+#elif defined(_AIX)
+# define VCWD_ACCESS(pathname, mode) access_aix(pathname, mode)
 #else
 #define VCWD_ACCESS(pathname, mode) access(pathname, mode)
 #endif
@@ -322,6 +362,8 @@
 #if HAVE_UTIME
 # ifdef ZEND_WIN32
 #  define VCWD_UTIME(path, time) win32_utime(path, time)
+# elif defined(_AIX)
+#  define VCWD_UTIME(path, time) utime_aix(path, time)
 # else
 #  define VCWD_UTIME(path, time) utime(path, time)
 # endif
diff -Nur php-7.0.3.orig/main/streams/plain_wrapper.c php-7.0.3-aix/main/streams/plain_wrapper.c
--- php-7.0.3.orig/main/streams/plain_wrapper.c	2016-02-02 17:32:32 +0100
+++ php-7.0.3-aix/main/streams/plain_wrapper.c	2016-03-14 13:03:22 +0100
@@ -988,7 +988,23 @@
 		}
 	}
 
+#ifdef _AIX
+	/*
+	On AIX, open() does not raise an error if the file name ends with a slash, it opens/creates
+	the file without the trailing slash.
+	For consistency with Linux, check if the name ends with a slash and simulate Linux behavior
+	in this case.
+	*/
+	if (realpath[strlen(realpath) - 1] == '/') {
+		fd = -1;
+		errno = EISDIR;	
+	}
+	else {
+		fd = open(realpath, open_flags, 0666);
+	}
+#else
 	fd = open(realpath, open_flags, 0666);
+#endif
 
 	if (fd != -1)	{
 

 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Nov 30 22:03:36 2021 UTC