The patch looks ok, a couple of questions though...
1) disktotalspace() looks like a memory intensive operation, perhaps
having a cache might not be a bad idea.
2) I see you use LoadLibrary to load in kernel32.dll on Win32, what
happens on that system when I call disk total space more than once?
Could this cause a crash?? Also, perhaps you don't need to load the
library in more than once, does anyone know of any other areas where
this library is loaded in?
3) Why not just have a statfs() function instead, that would return all
this info and more?
> Does anyone object to my adding a new function disktotalspace()?
>
> A friend of mine ran into a situation where he required an
> OS-independent means of determining the amount of free space on a
> filesystem (meaning executing and parsing 'df -k' wasn't going to
> cut it).
>
> PHP already has diskfreespace(), so I see no reason why it can't
> also have disktotalspace().
>
> His patch is attached. If no one objects, I'll commit this in a
> day or two (along with documentation, which I have yet to write).
>
>
>
> ------------------------------------------------------------------------
>
> ? php_cvs_disktotal_patch.diff
> ? disktotalspace.diff
> Index: basic_functions.c
> ===================================================================
> RCS file: /repository/php4/ext/standard/basic_functions.c,v
> retrieving revision 1.337
> diff -u -r1.337 basic_functions.c
> --- basic_functions.c 2001/05/14 20:56:05 1.337
> +++ basic_functions.c 2001/05/15 02:51:28
> @@ -505,6 +505,7 @@
> PHP_FE(chmod, NULL)
> PHP_FE(touch, NULL)
> PHP_FE(clearstatcache, NULL)
> + PHP_FE(disktotalspace, NULL)
> PHP_FE(diskfreespace, NULL)
>
> /* functions from mail.c */
> Index: filestat.c
> ===================================================================
> RCS file: /repository/php4/ext/standard/filestat.c,v
> retrieving revision 1.65
> diff -u -r1.65 filestat.c
> --- filestat.c 2001/05/14 18:30:07 1.65
> +++ filestat.c 2001/05/15 02:51:28
> @@ -124,6 +124,107 @@
> return SUCCESS;
> }
>
> +/* {{{ proto double disktotalspace(string path)
> + Get total diskspace for filesystem that path is on */
> +PHP_FUNCTION(disktotalspace)
> +{
> + pval **path;
> +#ifdef WINDOWS
> + double bytestotal;
> +
> + HINSTANCE kernel32;
> + FARPROC gdfse;
> + typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER,
>PULARGE_INTEGER);
> + gdfse_func func;
> +
> + /* These are used by GetDiskFreeSpaceEx, if available. */
> + ULARGE_INTEGER FreeBytesAvailableToCaller;
> + ULARGE_INTEGER TotalNumberOfBytes;
> + ULARGE_INTEGER TotalNumberOfFreeBytes;
> +
> + /* These are used by GetDiskFreeSpace otherwise. */
> + DWORD SectorsPerCluster;
> + DWORD BytesPerSector;
> + DWORD NumberOfFreeClusters;
> + DWORD TotalNumberOfClusters;
> +
> +#else /* not - WINDOWS */
> +#if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
> + struct statvfs buf;
> +#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_STATFS)
> + struct statfs buf;
> +#endif
> + double bytestotal = 0;
> +#endif /* WINDOWS */
> +
> + if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1,&path)==FAILURE) {
> + WRONG_PARAM_COUNT;
> + }
> +
> + convert_to_string_ex(path);
> +
> + if (php_check_open_basedir((*path)->value.str.val)) RETURN_FALSE;
> +
> +#ifdef WINDOWS
> + /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
> + so we have to jump through some hoops to see if the function
> + exists. */
> + kernel32 = LoadLibrary("kernel32.dll");
> + if (kernel32) {
> + gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
> + /* It's available, so we can call it. */
> + if (gdfse) {
> + func = (gdfse_func)gdfse;
> + if (func((*path)->value.str.val,
> + &FreeBytesAvailableToCaller,
> + &TotalNumberOfBytes,
> + &TotalNumberOfFreeBytes) == 0) RETURN_FALSE;
> +
> + /* i know - this is ugly, but i works ([EMAIL PROTECTED]) */
> + bytestotal = TotalNumberOfBytes.HighPart *
> + (double) (((unsigned long)1) << 31) * 2.0 +
> + TotalNumberOfBytes.LowPart;
> + }
> + /* If it's not available, we just use GetDiskFreeSpace */
> + else {
> + if (GetDiskFreeSpace((*path)->value.str.val,
> + &SectorsPerCluster, &BytesPerSector,
> + &NumberOfFreeClusters, &TotalNumberOfClusters) == 0)
>RETURN_FALSE;
> + bytestotal = (double)TotalNumberOfClusters *
>(double)SectorsPerCluster * (double)BytesPerSector;
> + }
> + }
> + else {
> + php_error(E_WARNING, "Unable to load kernel32.dll");
> + RETURN_FALSE;
> + }
> +
> +#elif defined(OS2)
> + {
> + FSALLOCATE fsinfo;
> + char drive = (*path)->value.str.val[0] & 95;
> +
> + if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo,
>sizeof( fsinfo ) ) == 0)
> + bytestotal = (double)fsinfo.cbSector * fsinfo.cSectorUnit *
>fsinfo.cUnit;
> + }
> +#else /* WINDOWS, OS/2 */
> +#if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
> + if (statvfs((*path)->value.str.val,&buf)) RETURN_FALSE;
> + if (buf.f_frsize) {
> + bytestotal = (((double)buf.f_blocks) * ((double)buf.f_frsize));
> + } else {
> + bytestotal = (((double)buf.f_blocks) * ((double)buf.f_bsize));
> + }
> +
> +#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_STATFS)
> + if (statfs((*path)->value.str.val,&buf)) RETURN_FALSE;
> + bytestotal = (((double)buf.f_bsize) * ((double)buf.f_blocks));
> +#endif
> +#endif /* WINDOWS */
> +
> + RETURN_DOUBLE(bytestotal);
> +}
> +/* }}} */
> +
> /* {{{ proto double diskfreespace(string path)
> Get free diskspace for filesystem that path is on */
> PHP_FUNCTION(diskfreespace)
> Index: php_filestat.h
> ===================================================================
> RCS file: /repository/php4/ext/standard/php_filestat.h,v
> retrieving revision 1.10
> diff -u -r1.10 php_filestat.h
> --- php_filestat.h 2001/05/11 19:55:44 1.10
> +++ php_filestat.h 2001/05/15 02:51:28
> @@ -43,6 +43,7 @@
> PHP_FUNCTION(file_exists);
> PHP_NAMED_FUNCTION(php_if_stat);
> PHP_NAMED_FUNCTION(php_if_lstat);
> +PHP_FUNCTION(disktotalspace);
> PHP_FUNCTION(diskfreespace);
> PHP_FUNCTION(chown);
> PHP_FUNCTION(chgrp);
>
>
> Part 1.1
>
> Content-Type:
>
> text/plain
>
>
> ------------------------------------------------------------------------
> disktotalspace.diff
>
> Content-Type:
>
> text/plain
>
>
> ------------------------------------------------------------------------
> Part 1.3
>
> Content-Type:
>
> text/plain
>
>
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]