Remove obsolete platforms ifdefs from PAL (#8971)
[platform/upstream/coreclr.git] / src / pal / src / file / disk.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*++
6
7
8
9 Module Name:
10
11     disk.c
12
13 Abstract:
14
15     Implementation of the disk information functions.
16
17 Revision History:
18
19
20
21 --*/
22
23 #include "pal/palinternal.h"
24 #include "pal/dbgmsg.h"
25 #include "pal/file.h"
26 #include "pal/stackstring.hpp"
27
28 #include <sys/param.h>
29 #include <sys/mount.h>
30 #include <errno.h>
31 #if HAVE_STATVFS
32 #include <sys/types.h>
33 #include <sys/statvfs.h>
34 #define statfs  statvfs
35 #if STATVFS64_PROTOTYPE_BROKEN
36 typedef statvfs_t pal_statfs;
37 #else // STATVFS64_PROTOTYPE_BROKEN
38 typedef struct statvfs pal_statfs;
39 #endif // STATVFS64_PROTOTYPE_BROKEN
40 #else // HAVE_STATVFS
41 typedef struct statfs pal_statfs;
42 #endif  // HAVE_STATVFS
43
44 SET_DEFAULT_DEBUG_CHANNEL(FILE);
45
46 /*++
47
48 Function:
49
50     GetDiskFreeSpaceW
51     
52 See MSDN doc.
53 --*/
54 PALIMPORT
55 BOOL
56 PALAPI
57 GetDiskFreeSpaceW(
58           LPCWSTR lpDirectoryName,
59           LPDWORD lpSectorsPerCluster,
60           LPDWORD lpBytesPerSector,
61           LPDWORD lpNumberOfFreeClusters,  /* Caller will ignore output value */
62           LPDWORD lpTotalNumberOfClusters) /* Caller will ignore output value */
63 {
64     BOOL bRetVal = FALSE;
65     pal_statfs fsInfoBuffer;
66     INT  statfsRetVal = 0;
67     DWORD dwLastError = NO_ERROR;
68     PathCharString dirNameBufferPathString;
69     size_t length;
70     char * dirNameBuffer;
71     int size;
72
73     PERF_ENTRY(GetDiskFreeSpaceW);
74     ENTRY( "GetDiskFreeSpaceW( lpDirectoryName=%p (%S), lpSectorsPerCluster=%p,"
75            "lpBytesPerSector=%p, lpNumberOfFreeClusters=%p, "
76            "lpTotalNumberOfClusters=%p )\n", lpDirectoryName ? lpDirectoryName :
77             W16_NULLSTRING, lpDirectoryName ? lpDirectoryName :
78             W16_NULLSTRING, lpSectorsPerCluster, lpBytesPerSector, 
79             lpNumberOfFreeClusters, lpTotalNumberOfClusters );
80
81     /* Sanity checks. */
82     if ( !lpSectorsPerCluster )
83     {
84         ERROR( "lpSectorsPerCluster cannot be NULL!\n" );
85         dwLastError = ERROR_INVALID_PARAMETER;
86         goto exit;
87     }
88     if ( !lpBytesPerSector )
89     {
90         ERROR( "lpBytesPerSector cannot be NULL!\n" );
91         dwLastError = ERROR_INVALID_PARAMETER;
92         goto exit;
93     }
94     if ( lpNumberOfFreeClusters || lpTotalNumberOfClusters )
95     {
96         TRACE("GetDiskFreeSpaceW is ignoring lpNumberOfFreeClusters"
97               " and lpTotalNumberOfClusters\n" );
98     }
99     if ( lpDirectoryName && PAL_wcslen( lpDirectoryName ) == 0 )
100     {
101         ERROR( "lpDirectoryName is empty.\n" );
102         dwLastError = ERROR_INVALID_PARAMETER;
103         goto exit;
104     }
105
106     /* Fusion uses this API to round file sizes up to their actual size
107        on-disk based on the BytesPerSector * SectorsPerCluster.
108        The intent is to avoid computing the sum of all file sizes in the
109        cache just in bytes and not account for the cluster-sized slop, when
110        determining if the cache is too large or not. */
111
112     if ( lpDirectoryName )
113     {
114         length = (PAL_wcslen(lpDirectoryName)+1) * 3;
115         dirNameBuffer = dirNameBufferPathString.OpenStringBuffer(length);
116         if (NULL == dirNameBuffer)
117         {
118             dwLastError = ERROR_NOT_ENOUGH_MEMORY;
119             goto exit;
120         }
121
122         size = WideCharToMultiByte( CP_ACP, 0, lpDirectoryName, -1,
123                                   dirNameBuffer,length, 0, 0 );
124         dirNameBufferPathString.CloseBuffer(size);
125         if ( size != 0 )
126         {
127             FILEDosToUnixPathA( dirNameBuffer );
128             statfsRetVal = statfs( dirNameBuffer, &fsInfoBuffer );
129         }
130         else
131         {
132             ASSERT( "Unable to convert the lpDirectoryName to multibyte.\n" );
133             dwLastError = ERROR_INTERNAL_ERROR;
134             goto exit;
135         }
136     }
137     else
138     {
139         statfsRetVal = statfs( "/", &fsInfoBuffer );
140     }
141
142     if ( statfsRetVal == 0 )
143     {
144         *lpBytesPerSector = fsInfoBuffer.f_bsize;
145         *lpSectorsPerCluster = 1;
146         bRetVal = TRUE;
147     }
148     else
149     {
150         if ( errno == ENOTDIR || errno == ENOENT )
151         {
152             FILEGetProperNotFoundError( dirNameBuffer, &dwLastError );
153             goto exit;
154         }
155         dwLastError = FILEGetLastErrorFromErrno();
156         if ( ERROR_INTERNAL_ERROR == dwLastError )
157         {
158             ASSERT("statfs() not expected to fail with errno:%d (%s)\n", 
159                    errno, strerror(errno));
160         }
161         else
162         {
163             TRACE("statfs() failed, errno:%d (%s)\n", errno, strerror(errno));
164         }
165     }
166
167 exit:
168     if ( NO_ERROR != dwLastError )
169     {
170         SetLastError( dwLastError );
171     }
172
173     LOGEXIT( "GetDiskFreeSpace returning %s.\n", bRetVal == TRUE ? "TRUE" : "FALSE" );
174     PERF_EXIT(GetDiskFreeSpaceW);
175     return bRetVal;
176 }
177