路径: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; }