• 环境编程代码实例:“加/卸载” 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{}; // 系统文件向量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    函数

    // 在配置文件的一行字符串【键 = 值换行符】中,依据键获取值
    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[])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    执行命令函数

    // 执行命令
    // 输入:命令,参数数组,参数数量
    // 注意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;
    }
    
    • 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

    主函数

    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;
    }
    
    • 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

    拓展

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

    总结

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


    参考资料

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

    作者的话

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

  • 相关阅读:
    软件工程毕业设计课题(81)微信小程序毕业设计PHP校园跑腿小程序系统设计与实现
    java 获取15秒之前的时间
    C#教程15: 数据容器(collection)
    iOS打基础之Block二三事
    Elasticsearch8.2扩容挪数据master出现异常
    「Kafka」监控、集成篇
    java设计模式,简单工厂和抽象工厂有什么区别?
    Ai数字人直播系统SaaS源码大开源,源码独立部署助力中小企业发展!
    java中lambda表达式之函数式接口
    力扣大厂热门面试算法题 27-29
  • 原文地址:https://blog.csdn.net/m0_62083249/article/details/134021501