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]

Reply via email to