kexec代码详解4 - lzma.c解析2

it2023-05-06  75

路径:kexec-tools-2.0.20\kexec\lzma.c

 

//接口封装函数,调用了真正的功能实现函数lzopen_internal

LZFILE *lzopen(const char *path, const char *mode) {     return lzopen_internal(path, mode, -1); }

 

static LZFILE *lzopen_internal(const char *path, const char *mode, int fd) {     int level = 5;     int encoding = 0;     FILE *fp;     LZFILE *lzfile;     lzma_ret ret;     lzma_stream lzma_strm_tmp = LZMA_STREAM_INIT;

    //依次解析mode

    for (; *mode; mode++) {         if (*mode == 'w') //写模式encoding置1             encoding = 1;         else if (*mode == 'r') //读模式encoding置0             encoding = 0;         else if (*mode >= '1' && *mode <= '9') //如果模式中有[1,9]之间的,则取十进制整数值             level = *mode - '0';     }

    //已有文件描述符,则通过fdopen函数将文件描述符转换为FILE *     if (fd != -1)         fp = fdopen(fd, encoding ? "w" : "r");

    //否则根据实际路径打开文件,生成FILE *     else         fp = fopen(path, encoding ? "w" : "r");

    //如果打开失败,返回NULL     if (!fp)         return NULL;

    //分配LZFILE结构体,保存关键数据

    lzfile = calloc(1, sizeof(*lzfile));

    //如果失败,关闭之前打开的文件,返回NULL

    if (!lzfile) {         fclose(fp);         return NULL;     }

    lzfile->file = fp;     lzfile->encoding = encoding;     lzfile->eof = 0;     lzfile->strm = lzma_strm_tmp;     if (encoding) {         lzma_options_lzma opt_lzma;         if (lzma_lzma_preset(&opt_lzma, level - 1))             return NULL;         ret = lzma_alone_encoder(&lzfile->strm, &opt_lzma);     } else {         ret = lzma_auto_decoder(&lzfile->strm,                     UINT64_C(64) * 1024 * 1024, 0);     }     if (ret != LZMA_OK) {         fclose(fp);         free(lzfile);         return NULL;     }     return lzfile; }

最新回复(0)