我需要一个简单的方法来获得辅助存储的细节(如总大小,使用和自由空间)在一个(守护程序)的Linux C代码;
这些都是我尝试过的
- statvfs -不知道如何获取磁盘详细信息而不是文件
- 使用system(
df -h --total | grep total > disk.stat
)中的C代码然后读取该文件。
但上述操作涉及文件写入和读取,效率不高,因为此C代码是一个守护进程,它将持续轮询系统细节,作为图形生成的输入。
如果没有其他的方法,告诉我一个简单快速的ipc机制,并举例说明这个bash和C代码之间的通信。
/*
* @breif returns total percentage of secondary storage used
*
* - uses bash command to get storage data and store in a file
* - and use c code retrive the percent of usage from file and return it
*/
int calculate_storage_size( )
{
if ( system("df -h --total | grep total > disk.stat") >= 0 )
{
char *temp_char_ptr = (char *)NULL;
int storage_size_percent = -1;
FILE *fp ;
fp = fopen ("disk.stat" , "r");
if (fp != (FILE *)NULL)
{
temp_char_ptr = (char*) calloc ( 6 , 1 );
fscanf( fp,"%s %s %s %s %d", temp_char_ptr, temp_char_ptr, temp_char_ptr, temp_char_ptr, &storage_size_percent);
}
free (temp_char_ptr);
fclose(fp);
return storage_size_percent;
}
return -1;
}
4条答案
按热度按时间dxxyhpgq1#
我建议最好让用户指定在总数中应该考虑哪些挂载,或者使用启发式方法忽略系统挂载和临时挂载。
请考虑以下示例
info.c
:statistics()
函数接受一个以NULL结尾的装入点数组,以及两个指向无符号64位整数的指针。如果成功,函数返回0,否则返回非零错误代码。如果成功,函数将把文件系统中的总字节数设置为第一个整数,并把第二个整数设置为空闲字节数。如果你提供了一个或多个挂载点作为命令行参数,那么只考虑那些挂载点(POSIX说
argv[argc] == NULL
,所以这种用法是安全的)。否则,将使用
normal_mounts()
函数解析/proc/mounts
以获取“正常”挂载点列表。(行)从内核提供的伪文件中。所有tmpfs
(ramdisk)和swap
文件系统,以及那些装载在/proc
、/boot
、/sys
、/run
、/dev
、/mnt
、/media
和/var/run
。这只是一个粗略的启发式方法,不是已知的好方法。在守护进程中,甚至在图形应用程序中,您只调用(相当于)
statistics()
函数,使用相同的挂载点数组。您甚至可以考虑单独跟踪每个挂载点,让用户过滤和合并他们感兴趣的信息。实际上,我建议:我个人可能对查看临时文件使用的波动(在/tmp
和/var/tmp
是tmpfs挂载的机器上)以及跟踪我对/home
的长期使用感兴趣。在守护进程中,您可以使用
HUP
或USR1
或USR2
信号来指示用户希望您何时重新加载配置--这里是装载点列表。我不认为将其集成到DBUS中来检测可移动介质的装载/卸载会有什么意义,但如果您认为有用,当然可以这样做。如果您使用例如
并运行
它会输出类似于
其中第一行输出到标准错误,字节行输出到标准输出。您还可以专门命名挂载点--确保它们是不同的,因为代码不会检查重复的挂载--:
如果您想知道如何确定两个目录是否位于同一装载上:在一个路径上调用
stat(path1, &info1)
,在另一个路径上调用stat(path2, &info2)
。当且仅当(info1.st_dev == info2.st_dev)
时,这两个路径在同一个挂载上。(一个设备可以在不同的点上挂载多次,例如使用 bind mounts,但通常上述检查就足够了。)如果您觉得上面的代码都很烦人,可以使用
df
实用程序,要确保输出是C/POSIX语言环境(而不是法语或芬兰语),请使用或类似的,并使用
len = getline(&line, &size, handle)
读取输出。jecbmhm32#
您可以使用
popen()
代替system()/fopen()
:该系统将给予你一个可读的文件,而不使用硬盘驱动器。uwopmtnx3#
除了系统和文件杂牌机之外,没有可移植的ANSI C机制,即使这样也有点像幻觉,因为它依赖于df的存在。然而,Posix函数popen()本质上做的是同样的事情,但是给你的输出是FILE *。
z5btuh9x4#
我终于做到了statvfs本身,它工作得很好。