summaryrefslogtreecommitdiffstats
path: root/compat/disk.h
blob: 23bc1bef86c87a0853b87d75e0fc35ea1932f99d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#ifndef COMPAT_DISK_H
#define COMPAT_DISK_H

#include "abspath.h"
#include "gettext.h"

static int get_disk_info(struct strbuf *out)
{
	struct strbuf buf = STRBUF_INIT;
	int res = 0;

#ifdef GIT_WINDOWS_NATIVE
	char volume_name[MAX_PATH], fs_name[MAX_PATH];
	DWORD serial_number, component_length, flags;
	ULARGE_INTEGER avail2caller, total, avail;

	strbuf_realpath(&buf, ".", 1);
	if (!GetDiskFreeSpaceExA(buf.buf, &avail2caller, &total, &avail)) {
		error(_("could not determine free disk size for '%s'"),
		      buf.buf);
		res = -1;
		goto cleanup;
	}

	strbuf_setlen(&buf, offset_1st_component(buf.buf));
	if (!GetVolumeInformationA(buf.buf, volume_name, sizeof(volume_name),
				   &serial_number, &component_length, &flags,
				   fs_name, sizeof(fs_name))) {
		error(_("could not get info for '%s'"), buf.buf);
		res = -1;
		goto cleanup;
	}
	strbuf_addf(out, "Available space on '%s': ", buf.buf);
	strbuf_humanise_bytes(out, avail2caller.QuadPart);
	strbuf_addch(out, '\n');
#else
	struct statvfs stat;

	strbuf_realpath(&buf, ".", 1);
	if (statvfs(buf.buf, &stat) < 0) {
		error_errno(_("could not determine free disk size for '%s'"),
			    buf.buf);
		res = -1;
		goto cleanup;
	}

	strbuf_addf(out, "Available space on '%s': ", buf.buf);
	strbuf_humanise_bytes(out, (off_t)stat.f_bsize * (off_t)stat.f_bavail);
	strbuf_addf(out, " (mount flags 0x%lx)\n", stat.f_flag);
#endif

cleanup:
	strbuf_release(&buf);
	return res;
}

#endif /* COMPAT_DISK_H */