c - 在 Linux 上使用 C 语言调用 sysctl() 的示例
问题描述
我已经阅读了一些关于在 C 中使用 sysctl() 调用的警告,似乎如果我不能安全地使用 sysctl(),我能找到的唯一另一种方法是使用类似的东西:
system("echo fs.inotify.max_user_watches=NEW_MAX_DIRECTORIES >> /etc/sysctl.conf");
system("sysctl -p");
(当然,这假设确保二进制文件以 root 身份运行。但是,我宁愿不必使用系统调用来解决问题。
有人可以指出使用 sysctl() 的正确和安全吗?
这是我正在使用的代码片段。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
int main ()
{
int ret;
const char *LOGNAME="iNotifyMonitor";
logger(INFO, "================================================");
ret = startDaemon();
daemonRunning = ret;
if (ret == 0)
{
daemonRunning = 1;
FIRST_RUN = 0;
}
if(ret)
{
syslog(LOG_USER | LOG_ERR, "Error starting iNotifyMonitor");
logger(ERR, "Unable to start iNotifyMonitor");
closelog();
return EXIT_FAILURE;
}
signal(SIGINT, signalHandler);
signal(SIGHUP, signalHandler);
char *log_file_name = malloc(sizeof(char *) * sizeof(char *));
sprintf(log_file_name, "%s%s", INM_LOG_DIR, INM_LOG_FILE);
/* Try to open log file to this daemon */
if (INM_OPEN_LOG && INM_LOG_FILE)
{
log_stream = fopen(concatString(INM_LOG_DIR, INM_LOG_FILE), "a+");
if (log_stream == NULL)
{
char *errMsg;
sprintf(errMsg, "Cannot open log file %s, error: %s", concatString(INM_LOG_DIR, INM_LOG_FILE), strerror(errno));
log_stream = stdout;
}
}
else
{
log_stream = stdout;
}
while (daemonRunning == 1)
{
if (ret < 0)
{
logger(LOG_ERR, "Can not write to log stream: %s, error: %s", (log_stream == stdout) ? "stdout" : log_file_name, strerror(errno));
break;
}
ret = fflush(log_stream);
if (ret != 0)
{
logger(LOG_ERR, "Can not fflush() log stream: %s, error: %s",
(log_stream == stdout) ? "stdout" : log_file_name, strerror(errno));
break;
}
int curcount =countDirectory("/home/darrinw/Development/CrossRoads/");
directoryCount = curcount;
if(directoryCounrt > INM_MAX_DIRECTORIES)
{
int newVal = roundUp(directoryCount, 32768);
// call to sysctl() to modify fs.inotify.max_users_watches=newVal
}
sleep(INM_SCAN_INTERVAL);
}
解决方案
我的理解是,现代推荐的访问 sysctl 变量的方法是通过/proc/sys
. 所以只要打开/proc/sys/fs/inotify/max_user_watches
并在那里写。
int fd = open("/proc/sys/fs/inotify/max_user_watches", O_WRONLY);
dprintf(fd, "%d", NEW_MAX_DIRECTORIES);
close(fd);
错误检查留作练习。
修改/etc/sysctl.conf
将使设置在重新启动后保持不变(假设您的发行版以这种方式使用该文件,我不确定它们是否都这样做)。自动这样做有点粗鲁。如果需要,最好使用文档来建议系统管理员自己做。
推荐阅读
- json - 在Javascript中将二进制文件从Excel xlsb文件解析为JSON
- c++ - ] 之前的预期主要表达?(C++)
- c - 是否可以为进程分配持久内存?
- postman - 如何使用预请求脚本构建 Postman url 查询
- javascript - 无法在 Kendo Grid 中对过滤后的列表进行排序
- opencv - 在 Windows 上使用 conda 安装 opencv 时出现 EEXIST 17 错误
- angular - 即使内部值没有改变,组件 getter 也会触发重新渲染
- python - 如何在 Python 中不使用 urlib2.urlopen 读取 URL?
- c# - 无法从受 Azure AD B2C 保护的 MVC Web 应用程序访问 WebApi
- chart.js - 在 chart.js 中绘制一个带有列的圆环图来表示每小时的统计数据