环境编程代码实例:“加/卸载” Zend Framework 2

前言

环境编程代码实例:“加/卸载” Zend Framework 2。


代码仓库


需求介绍

现状:已存在旧生产项目,系统使用 Zend Framework 2(基于 PHP 的 Web MVC 框架,简称 ZF2)

目标:简化 ZF2 的配置

内容:

  1. 将 ZF2 的供应镜像可执行文件加载到内存,并映射/解映射到虚拟设备的一个分区
  2. 将虚拟设备的文件系统挂/卸载到目录

实现:

  • 环境:FreeBSD(服务器)
  • 语言:C/C++(程序)
  • 核心:执行 Shell 命令(程序使用 UNIX -> FreeBSD 的系统调用)
  • 要求:可靠(尽可能地考虑并处理错误情况)

代码

说明

  • 由于代码篇幅较多,在博客中直接粘贴并呈现会显得冗长,因此未在博客中放置完整代码,只展示核心片段代码。请前往"代码仓库"查看或获取相关代码
  • 注释有详细解析

文件结构

  • 文件夹:load_ZF2
  • 源文件:main.cpp
  • 可执行文件:main
  • 说明文件:readme.txt
  • 配置文件:setupvendor.conf
  • ZF2 的供应镜像文件:ZF2VendorImage.bin(因为是生产项目,未将该文件开源在代码仓库

核心片段

结构体和全局变量

struct SystemFile // 系统文件
{
    string file_name;   // 文件名称
    string virtual_dev; // 挂载设备号
    string mount_dir;   // 挂载目录
};

// const string g_config_file_path("./setupvendor.conf"); // 配置文件路径
const string g_config_file_path("/usr/local/etc/setupvendor.conf"); // 配置文件路径
const string g_file_num_key("file_num");                            // 配置文件中系统文件数量的键
string g_file_num_value("");                                        // 配置文件中系统文件数量的值
int g_file_num_value2 = 0;                                          // 配置文件中系统文件数量的值2

const string g_file_name_key("file_name");     // 配置文件中系统文件名称的键
const string g_virtual_dev_key("virtual_dev"); // 配置文件中虚拟设备号的键
const string g_mount_dir_key("mount_dir");     // 配置文件中挂载目录的键
vector<struct SystemFile> g_system_file_vec{}; // 系统文件向量

函数

// 在配置文件的一行字符串【键 = 值换行符】中,依据键获取值
void get_key_value(const string &line, const string &key, string &value)

// 获取系统文件数量
void get_system_file_num()

// 获取系统文件配置
void get_system_file_config()

// 执行命令
// 输入:命令,参数数组,参数数量
// 注意execv需要char*const*参数
void exec_cmd(const char *cmd, char *const arg[], const int arg_size)

// 挂载文件系统
void mount_file_system()

// 卸载文件系统
void umount_file_system()

int main(int argc, char *argv[])

执行命令函数

// 执行命令
// 输入:命令,参数数组,参数数量
// 注意execv需要char*const*参数
void exec_cmd(const char *cmd, char *const arg[], const int arg_size)
{
    for (int i = 0; i < arg_size; ++i)
    {
        cout << arg[i] << " ";
    }
    cout << endl;

    pid_t pid = fork(); // 进程号
    if (pid == -1)
    {
        perror("exec_cmd() fork() error");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0)
    {
        execv(cmd, arg);
    }

    // pid != 0
    int ret = -1;                   // 系统调用返回结果
    int status = 0;                 // 进程结束状态
    ret = waitpid(pid, &status, 0); // 等待子进程,结束状态,阻塞等待
    if ((ret == -1) || ((WIFEXITED(status)) && (WEXITSTATUS(status) != 0)))
    {
        perror("exec_cmd() Execute command error");
        exit(EXIT_FAILURE);
    }

    return;
}

主函数

int main(int argc, char *argv[])
{
    // 依据参数判断挂载或卸载文件系统
    if (argc >= 3)
    {
        cerr << "main() Argument number error" << endl;
        exit(EXIT_FAILURE);
    }
    if ((argc == 2) && (((strncmp(argv[1], "umount", 6)) != 0)))
    {
        cerr << "main() Invalid argument error" << endl;
        exit(EXIT_FAILURE);
    }

    get_system_file_num();    // 获取系统文件数量
    get_system_file_config(); // 获取系统文件配置

    if ((argc == 2) && (((strncmp(argv[1], "umount", 6)) == 0))) // 有2个参数且第二个是umount,则卸载文件系统
    {
        umount_file_system();
        return 0;
    }
    mount_file_system(); // 默认1个参数挂载文件系统
    return 0;
}

拓展

  • 该份实例实际上是在 UNIX/FreeBSD/Linux 环境使用 C/C++ 程序执行 Shell 命令的特例版本
  • 看懂代码后,稍加修改,该份实例可以成为通用版本

总结

环境编程代码实例:“加/卸载” Zend Framework 2。


参考资料

  • 《UNIX环境高级编程(第3版)》作者:W.Richard Stevens,Stephen A.Rago

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值