Re: [INTERNALS-WIN] chDir, chDrive, #35691
[email protected] ("Pierre Joye")
| Newsgroups | php.internals.win |
|---|---|
| Message-ID | <[email protected]> |
Hi! On Mon, Jun 23, 2008 at 10:40 PM, Pierre Joye <[email protected]> wrote: > On Mon, Jun 23, 2008 at 10:23 PM, Andi Gutmans <[email protected]> wrote: >> Can you share the patch before committing? This is pretty touchy stuff >> and we need to make sure we don't break anything else (incl. >> performance) when we put this in. > > It is pretty much the same as: > > chdir('d:\public_html'); > > when public_html is the current dir on d: > > except that it is actually a bit faster than calling chdir() only > (userland comparison) because you know that the path is absolute (no > check in virtual_chdir_file). > > I will post the patch once I managed to sit down to write it :) I > thought I would have enough time to do it today. My initial thought was to add this feature at the TSRM level to allow some small optimization. But given the gain, it was not worth it. The current patch adds three functions. The names used are the same as in msdn or other language and use the letter syntax (C/C++ API uses the driver number, 1=>A, 2=>B. VB and other high level language uses a single letter to define a drive). - getdrive - chdrive - getdcwd There is no impact on anything else in php as the functions are self contained and rely on TSRM to change the CWD. Sample usage: var_dump(getcwd()); var_dump(chdrive('D')); var_dump(getcwd()); var_dump(getdrive()); var_dump(getdcwd('c')); Output: string(24) "C:\php-sdk\2k5\x86\php53" bool(true) string(3) "D:\" string(1) "D" string(24) "C:\php-sdk\2k5\x86\php53" Cheers, -- Pierre http://blog.thepimp.net | http://www.libgd.org
windows_drive.patch.txt
(text/plain, 5.1 KB)
Index: basic_functions.c
===================================================================
RCS file: /repository/php-src/ext/standard/basic_functions.c,v
retrieving revision 1.725.2.31.2.64.2.35
diff -u -r1.725.2.31.2.64.2.35 basic_functions.c
--- basic_functions.c 25 May 2008 14:06:13 -0000 1.725.2.31.2.64.2.35
+++ basic_functions.c 24 Jun 2008 10:08:44 -0000
@@ -1072,6 +1072,22 @@
ZEND_ARG_INFO(0, directory)
ZEND_END_ARG_INFO()
+#ifdef PHP_WIN32
+static
+ZEND_BEGIN_ARG_INFO(arginfo_getdrive, 0)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_chdrive, 0)
+ ZEND_ARG_INFO(0, drive)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_getdcwd, 0)
+ ZEND_ARG_INFO(0, drive)
+ZEND_END_ARG_INFO()
+#endif
+
static
ZEND_BEGIN_ARG_INFO(arginfo_getcwd, 0)
ZEND_END_ARG_INFO()
@@ -3559,6 +3575,12 @@
PHP_FE(closedir, arginfo_closedir)
PHP_FE(chdir, arginfo_chdir)
+#ifdef PHP_WIN32
+ PHP_FE(getdrive, arginfo_getdrive)
+ PHP_FE(chdrive, arginfo_chdrive)
+ PHP_FE(getdcwd, arginfo_getdcwd)
+#endif
+
#if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC
PHP_FE(chroot, arginfo_chroot)
#endif
Index: dir.c
===================================================================
RCS file: /repository/php-src/ext/standard/dir.c,v
retrieving revision 1.147.2.3.2.12.2.7
diff -u -r1.147.2.3.2.12.2.7 dir.c
--- dir.c 11 Jun 2008 09:01:56 -0000 1.147.2.3.2.12.2.7
+++ dir.c 24 Jun 2008 10:21:18 -0000
@@ -306,6 +306,118 @@
/* }}} */
#endif
+#ifdef PHP_WIN32
+/* {{{ proto bool chdrive(string directory)
+ Change the current drive */
+PHP_FUNCTION(getdrive)
+{
+ int drivenr;
+ char drive[2] = "";
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ /* backup current drive to restore it if safemode or open_basedir fail */
+ drivenr = _getdrive();
+ drive[0] = (char)(drivenr + 'A' - 1);
+ RETURN_STRINGL(drive, 1, 1);
+}
+/* }}} */
+
+/* {{{ proto bool chdrive(string directory)
+ Change the current drive */
+PHP_FUNCTION(chdrive)
+{
+ char *drive;
+ int ret, drive_len, drivenr, olddrive;
+ char path[MAXPATHLEN];
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &drive, &drive_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (drive_len > 0) {
+ drive[0] = toupper(drive[0]);
+ if ((drive[0] < 'A' || drive[0] > 'Z')) {
+ RETURN_FALSE;
+ }
+ } else {
+ RETURN_FALSE;
+ }
+
+ /* backup current drive to restore it if safemode or open_basedir fail */
+ olddrive = _getdrive();
+
+ drivenr = drive[0] - 'A' + 1;
+ ret = _chdrive(drivenr);
+ if (ret != 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
+ RETURN_FALSE;
+ }
+
+ if (_getdcwd(drivenr, path, MAXPATHLEN) == NULL ) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
+ ret = _chdrive(olddrive);
+ if (ret != 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
+ }
+ RETURN_FALSE;
+ }
+
+ if ((PG(safe_mode) && !php_checkuid(path, NULL, CHECKUID_CHECK_FILE_AND_DIR)) || php_check_open_basedir(path TSRMLS_CC)) {
+ ret = _chdrive(olddrive);
+ if (ret != 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
+ }
+ RETURN_FALSE;
+ }
+
+ ret = VCWD_CHDIR(path);
+ if (ret != 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
+ ret = _chdrive(olddrive);
+ if (ret != 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
+ }
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool chdrive(string directory)
+ Change the current drive */
+PHP_FUNCTION(getdcwd)
+{
+ int drivenr, drive_len;
+ char *drive;
+ char path[MAXPATHLEN];
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &drive, &drive_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (drive_len > 0) {
+ drive[0] = toupper(drive[0]);
+ if ((drive[0] < 'A' || drive[0] > 'Z')) {
+ RETURN_FALSE;
+ }
+ } else {
+ RETURN_FALSE;
+ }
+
+ drivenr = drive[0] - 'A' + 1;
+
+ if (_getdcwd(drivenr, path, MAXPATHLEN) == NULL ) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(path, 1);
+}
+/* }}} */
+#endif
+
/* {{{ proto bool chdir(string directory)
Change the current directory */
PHP_FUNCTION(chdir)
Index: php_dir.h
===================================================================
RCS file: /repository/php-src/ext/standard/php_dir.h,v
retrieving revision 1.24.2.1.2.1.2.1
diff -u -r1.24.2.1.2.1.2.1 php_dir.h
--- php_dir.h 31 Dec 2007 07:17:15 -0000 1.24.2.1.2.1.2.1
+++ php_dir.h 24 Jun 2008 10:07:55 -0000
@@ -27,6 +27,13 @@
PHP_FUNCTION(opendir);
PHP_FUNCTION(closedir);
PHP_FUNCTION(chdir);
+
+#ifdef PHP_WIN32
+PHP_FUNCTION(getdrive);
+PHP_FUNCTION(chdrive);
+PHP_FUNCTION(getdcwd);
+#endif
+
#if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC
PHP_FUNCTION(chroot);
#endif