- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
希望大家指出我明显的错误;
系统是嵌入式linux,代码是c语言
我们在cgi脚本中有一些代码,它接受来自(Boa)网络服务器的STDIN_FILENO数据流(文件上传)并将其写入临时文件(“/tmp/file.txt”)。
下面的代码是一个非常简化的代码片段,但基本上显示了事物的顺序:
预期的文件是一个二进制文件,大约 20Mb,但写入总是在大约 1.4Mb 时失败,并出现 errno 9 (EBADF),这表明文件描述符已以某种方式关闭。
有足够的磁盘空间,并且 Web 服务器不会限制 POST 文件大小或截断数据。
代码:
char buffer[1024];
mode_t fd_mode=S_IRWXU;
if ((targ_fd = open("/tmp/file.txt", O_WRONLY | O_CREAT, fd_mode)) == -1)
{
OUTPUT("Error opening file\n");
return FAIL;
}
while(total < maxlen)
{
count = read(STDIN_FILENO, buffer, 1024);
if(count > 0)
{
if(write(targ_fd, buffer, count) < 0)
{
perror("Failed to write to file");
close(targ_fd);
return FAIL;
}
total += count;
}
else
{
return FAIL;
// Or success if EOF, code omitted for clarity
}
}
对于较小的文件(但大到足以需要多次写入),它可以完美地工作。
非常感谢任何想法!
编辑添加:更新代码,以及:
我们确实捕获了 read() 返回 0,但为了清楚起见我省略了它。程序是单线程的,在最初从第一个 read() 数据中修剪 MIME header 后,它只是将其读入缓冲区,然后将缓冲区写入临时文件,直到达到 maxlen 或输入结束。
附加说明:写入最初会成功,创建一个包含正确内容的文件,直到失败时的大小。
通过进一步测试进行更新:以下有用的评论/建议:
count 是一个 int,符号性没有问题。
我忘记检查 write() 的返回值,失败前的最后一个 write() 未能写入请求的全部字节数。更改 open() 以添加标志 O_SYNC 没有任何区别。
我添加了 fstat() 并在 open() 和失败时进行调试打印:
代码:
printf("File type: ");
switch (filestat.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown?\n"); break;
}
printf("I-node number: %ld\n", (long) filestat.st_ino);
printf("Mode: %lo (octal)\n",
(unsigned long) filestat.st_mode);
printf("Link count: %ld\n", (long) filestat.st_nlink);
printf("Ownership: UID=%ld GID=%ld\n",
(long) filestat.st_uid, (long) filestat.st_gid);
printf("Preferred I/O block size: %ld bytes\n",
(long) filestat.st_blksize);
printf("File size: %lld bytes\n",
(long long) filestat.st_size);
printf("Blocks allocated: %lld\n",
(long long) filestat.st_blocks);
printf("Last status change: %s", ctime(&filestat.st_ctime));
printf("Last file access: %s", ctime(&filestat.st_atime));
printf("Last file modification: %s", ctime(&filestat.st_mtime));
打开时的结果是:
Fd = 5
File type: regular file
I-node number: 486
Mode: 100600 (octal)
Link count: 1
Ownership: UID=0 GID=0
Preferred I/O block size: 4096 bytes
File size: 0 bytes
Blocks allocated: 0
Last status change: Thu Jan 1 00:00:51 1970
Last file access: Thu Jan 1 00:00:51 1970
Last file modification: Thu Jan 1 00:00:51 1970
错误结果:
Fd = 5
Failed to write to the pipe (errno = 9), managed 273 / 4096 bytes
File type: regular file
I-node number: 486
Mode: 100600 (octal)
Link count: 1
Ownership: UID=0 GID=0
Preferred I/O block size: 4096 bytes
File size: 1499136 bytes
Blocks allocated: 2944
Last status change: Thu Jan 1 00:00:51 1970
Last file access: Thu Jan 1 00:00:51 1970
Last file modification: Thu Jan 1 00:00:51 1970
是的,系统时钟未设置。
更多信息:失败后:
root@IPNC:~# df -i /tmp
Filesystem Inodes Used Available Use% Mounted on
none 5664 7 5657 0% /tmp
root@IPNC:~# df /tmp
Filesystem 1K-blocks Used Available Use% Mounted on
none 25600 1508 24092 6% /tmp
根据要求提供更多信息:
正在进行的 MIME 修剪只是跳过第一个到达的数据,直到数据之前的“\r\n\r\n”,因此第一次写入开始从缓冲区的中途读取。我已经检查过,这是从正确的点开始并在正确的点结束,并且使用较小的测试文件(~50k),整个文件都被正确接收和写入,没有错误、重载或欠载。
进一步测试的结果:
嗯,还没解决。故障点随着不同的输入数据(文件大小和类型)而移动,但似乎不会绊倒任何特定的模式或数据(例如:一个文件在一大块 0xFF 的中间发生故障)。
我尝试过使用 fcntl() 来锁定 fd,使用 dup() 并处理新的 fd,以防另一个 fd 以某种方式从外部关闭,两者都没有任何区别。
我将尝试插入虚拟数据,看看是否可以成功写入 filesize 字节的虚拟数据。
**终于接近尾声了...**
看起来 Boa 以一种奇怪的方式处理 HTTP POST 请求,将它们写入临时文件,并将其复制到 objective-c GI 脚本的 STDIN。如果/tmp 中有足够的空间容纳两个副本,那就没问题,但没有(我们是嵌入的)。仍然存在一些奇怪的地方:它创建的文件永远不会出现在文件列表中,并且写入失败并不表示“空间不足”。肯定会发生一些奇怪的事情,但现在我认为这并不完全是 write() 的失败,而是父代码中的一些更大的问题。
最佳答案
好吧,我想我应该关闭这个......
答案有点复杂。
最初我说“我们有足够的磁盘空间”,我们确实这么做了,直到 Boa 决定将整个 POST 数据(约 20Mb)缓冲在/tmp 文件夹中(总可用空间约 25Mb),这使得写入将数据文件写入/tmp 非常棘手,并解释了为什么 write() 文件越小(大约 25Mb 减去文件大小)就越失败,大概如果文件是 12.5Mb,它就会成功。
无论如何,奇怪的返回代码(EBADF)而不是任何类型的空间不足指示使鹅追逐变得更加疯狂。
令人失望的结果是我们必须制定其他方案将文件直接上传到设备,无论是通过其他方式(tftp、wget)还是使用上传页面中的脚本来拆分文件分成 block 并一次上传一个 block 。
关于c - 尽管多次成功写入,但 Write() 仍导致 EBADF 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25722339/
我在使用以下代码时遇到问题: function http_file_exists($url){ $f=fopen($url,"r"); if($f){ fclose($f); retu
我已经通过 Git 部署到 Azure 几个月了,没有出现重大问题,但现在我似乎遇到了一个无法克服的错误。 我创建了一个新的 Azure 网站,为正在开发的项目创建单独的预览链接。我在新站点上设置了
我已经通过flutter创建了一个App并完成了它,我想在flutter文档中阅读时进行部署。 我收到此错误: FAILURE: Build failed with an exception. * W
我在Windows 10中使用一些简单的Powershell代码遇到了这个奇怪的问题,我认为这可能是我做错了,但我不是Powershell的天才。 我有这个: $ix = [System.Net.Dn
我正在尝试使用 RapidJSON 解析从服务器接收到的数据。以下是收到的确切字符串: [ { "Node": "9478149a08f9", "Address": "172.17
我尝试为 ios 编译 OpenCV。我总是收到这些错误。我用不同版本的opencv试了一下,结果都是一样的。 我运行这个:python 平台/ios/build_framework.py ios_o
我在一台机器上做基本的发布/订阅,我的客户端是 StackExchange-Redis 的 C# 客户端,我在同一台机器上运行基于 Windows 的 Redis 服务器(服务器版本 2.8.4) 当
我有这段代码,但无法执行,请帮我解决这个问题 连接 connect_error) { die ("connection failed: " . $terhubung->connect_erro
我在 tomcat 上运行并由 maven 编译的 Web 应用程序给出了以下警告和错误。我可以在本地存储库中看到所有 JAR,但有人可以帮忙吗。 WARNING: Failed to scan JA
我正在 Windows 8 上使用 Android Studio 开发一个 android 应用程序,我正在使用一些 native 代码。突然间我无法编译我的 C 文件。当我运行 ndk-build
下面的代码对类和结构的成员进行序列化和反序列化。序列化工作正常,但我在尝试使用 oarch >> BOOST_SERIALIZATION_NVP(outObj); 反序列化时遇到了以下错误; 代码中是
如果我运行此命令“rspec ./spec/requests/api/v1/password_reset_request_spec.rb”,此文件中的所有测试都会通过。 但是,当我运行“rspec”时
我在尝试执行测试以使用 Protractor 上传文件时出错,我的代码是这个 it('it should be possible to upload a file', function() {
System.loadLibrary("nativefaceswap"); 当我运行我的应用程序时,我在 Android Studio 中发现了此类错误。在logcat中显示: java.lang.U
我希望有人能帮助我!使用任何方法或命令行的任何 SSL/HTTPS 调用均无效。 我在 Windows 10 中使用 Ubuntu Server 18.04 作为子系统。我的问题是昨天才开始出现的,因
通过删除这两个值将日期字段从 null=True 和 Blank=True 更改为 required 时,使用 db.alter 命令时遇到问题。 当以下行被注释掉时,迁移运行不会出现问题。
我第一次使用 Heroku 尝试创建应用程序(使用 SendGrid 的 Inbound Parse Webhook"和 Twilio SMS 通过电子邮件发送和接收 SMS 消息)。通过 Virtu
我正在将我的 swift 项目更新到 Xcode 7 上的 Swift 2.0。xcode 在构建项目时报告了以下错误: 命令/Applications/Xcode.app/Contents/Deve
在我的代码中,SSL 库函数 SSL_library_init() 没有按预期返回 1。我如何才能看到它返回了什么错误? 我在 SSL_library_init() 之后调用了 SSL_load_er
我正在尝试运行在以下链接中找到的答案: Asynchronously Load the Contents of a Div 但是当我这样做时,我会遇到我不太理解的错误。 我的代码: $(documen
我是一名优秀的程序员,十分优秀!