【问题标题】:Copying an executable file in C在 C 中复制可执行文件
【发布时间】:2018-05-29 22:54:55
【问题描述】:

我在用 C 语言将文件从一个目录复制到另一个目录时遇到问题。具体来说,我的代码适用于文本文件,但不适用于可执行文件。写入的字节数是正确的,文件权限也是正确的,但是副本的结果类型不被文件系统识别为可执行文件(我正在使用 xubuntu 虚拟机)并且具有“未知”类型。因此,如果我在 bash 的命令行中回显 md5sum 的结果,它们是不同的。

在下面的代码中,“checkErrno”是我定义的一个调用 perror 的函数。 “currDir”是当前目录,“DIRNAME”是我要移动到的目录。所有库都正确包含,我只是复制并粘贴了重要的代码块。

struct stat fileSt;
if(stat(fileName,&fileSt) != 0) checkErrno("Stats file");
char currDir[PATH_MAX];
FILE* file;
if(getcwd(currDir,PATH_MAX) == NULL) checkErrno("Currdir");
if(chdir(DIRNAME) != 0) checkErrno("Chdir");
if((file = fopen(fileName,"w")) == NULL) checkErrno("Create file");
if(chmod(fileName, fileSt.st_mode & 07777)) perror("chmod");
if(fwrite(fileMsg.data.buf,1,fileSize,file) < fileSize) checkErrno("fwrite");
fflush(file);
if(fclose(file) != 0) checkErrno("fclose");
if(chdir(currDir) != 0) checkErrno("chdir");

提前致谢!

编辑:错误出在我用来读取文件的函数中。一旦我发现我很容易解决它。

【问题讨论】:

  • 尝试给出一个简短的完整程序。您在此处显示的代码缺少很多内容,例如您读取文件的方式。
  • 是的,很多代码丢失了......也许你的缓冲区“读取”不正确?请向我们展示您的阅读代码
  • 如果你不知道问题是什么,你怎么知道什么代码“重要”?
  • 文件由客户端在缓冲区中传递。我反复测试了读写功能,它适用于文本文件。它只是不适用于可执行文件。

标签: c file fwrite md5sum


【解决方案1】:

你的 chmod 会清除所有位而不是设置任何位

if(chmod(fileName, fileSt.st_mode & 07777))

您需要确保该副本被标记为至少可执行,也可能是可读的,(我不确定用户是否必须具有读取权限才能执行某些操作,但这是有意义的。

【讨论】:

  • 执行不需要读取权限 - 只要设置了执行标志,任何人都可以执行二进制文件,即使他们没有读取权限(在 Unix/POSIX 上为 true,不确定其他系统喜欢窗户)
【解决方案2】:

我不知道这是否是您的问题,但请记住以二进制模式打开这两个文件:“wb”而不是“w”,以及“rb”而不是“r”。

【讨论】:

  • 我也是这么想的......但是'b'真的有必要吗(现在试图搜索它,还没有找到明确的答案......虽然我倾向于同意你的观点)。 .你能发个链接吗?
  • @Grantly:在 Unix 上,通常不需要 'b'。
  • b 仅在 Windows(更准确地说,非 POSIX 系统)上是必需的,即使在 Windows 上,也只是为了避免格式化翻译,您不应该通过 @ 进行原始读取和写入987654322@ 和fwrite。它在 Windows 上与fscanf 等产生了巨大的差异。我在这里看不到。
  • @Grantly 是的,这是 100% 必要的——“b”表示文件不应被解释为文本——例如,在“r”中打开的窗口上会将“\n”呈现为“\r \n" 自动 - 而 "rb" 模式将保持所有字节不变 - 这是您在复制文件时想要的。因此,为了便携性,请始终使用“b”。
  • 啊哈,现在我知道我为什么感到困惑了——当我编写跨平台代码时……有时需要 b,有时不需要。但是是的 - Windows 需要'b'
猜你喜欢
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
相关资源
最近更新 更多