gpt4 book ai didi

c - NetBSD 上的 libmagic 关闭文件描述符

转载 作者:太空宇宙 更新时间:2023-11-03 23:46:51 24 4
gpt4 key购买 nike

我正在编写一个 FastCGI 来为 Web 提供商提供对静态内容的 zlib 压缩,但我在 NetBSD 上遇到了 mmap() 的问题。

#include <magic.h>
#ifndef MADV_DONTFORK
#define MADV_DONTFORK 0
#endif
#ifndef MADV_MERGEABLE
#define MADV_MERGEABLE 0
#endif
#ifndef MADV_HUGEPAGE
#define MADV_HUGEPAGE 0
#endif
#ifndef MADV_DONTDUMP
#define MADV_DONTDUMP 0
#endif

struct stat sb;
int fd=strcatn_open((char *)REQUEST_URI,"index.html")?:strcatn_open((char *)REQUEST_URI,"index.htm")?:open(REQUEST_URI, O_RDONLY);
if (fd==0)
HTTP_Return_Code("Status: 404 Not Found");
if(!strcmp(HTTP_CACHE_CONTROL?:"ch","no-cache")) { //avoid to compare with a NULL pointer
if(IfModifiedSince)
if(tdate_parse((char *)IfModifiedSince)==sb.st_mtime) // UNIX : can compare directly
HTTP_Return_Code("Status: 304 Not Modified\nCache-Control: public; max-age=2678400");
if(IfUnmodifiedSince)
if(tdate_parse((char *)IfUnmodifiedSince)==sb.st_mtime) // UNIX : can compare directly
HTTP_Return_Code("Status: 304 Not Modified\nCache-Control: public; max-age=2678400");
}
strftime(LastModified, sizeof(char)*30, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(sb.st_mtime)) ); // RFC1123 format : "%a, %d %b %Y %H:%M:%S GMT"
magic_t mime_type=magic_open(MAGIC_PRESERVE_ATIME|MAGIC_DEVICES|MAGIC_SYMLINK|MAGIC_MIME|MAGIC_COMPRESS);
magic_load(mime_type,NULL); // load default magic database
posix_fadvise(fd,0,sb.st_size,POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED);
send_HTTP_Headers("Content-encoding: gzip\nContent-Type: %s\nLast-Modified: %s\n",magic_descriptor(mime_type,fd),LastModified);
magic_close(mime_type);

//the problem is here
void * HTTP_file=mmap(NULL,sb.st_size,PROT_READ,MAP_SHARED|MAP_FILE,fd,0);
if(HTTP_file==(void *)-1)
err(1,"errno=%d",errno);
uLong maxCompressLen=compressBound(sb.st_size);
Bytef* destbuffer=(Bytef *)malloc((size_t)maxCompressLen);
compress2(destbuffer,&maxCompressLen,(const Bytef *)HTTP_file,sb.st_size,Z_BEST_COMPRESSION);
munmap(HTTP_file,sb.st_size);
close(fd);
madvise(destbuffer,(size_t)maxCompressLen,MADV_SEQUENTIAL | MADV_WILLNEED | MADV_DONTFORK | MADV_MERGEABLE | MADV_HUGEPAGE | MADV_DONTDUMP);
write(STDOUT_FILENO, destbuffer, (size_t)maxCompressLen);

当我将 fastCGI 函数转换为 printf()/scanf() 进行调试时,我在 NetBSD 上得到了这个:

Content-encoding: gzip
Content-Type: text/html; charset=utf-8
Last-Modified: Wed, 27 May 2015 01:15:28 GMT

compressor: errno=9: 错误的文件描述符对应于 mmap 手册页描述的 EBADF,因为fd 不是有效的打开文件描述符。我不明白,因为文件描述符对我来说似乎非常有效,因为它适用于 fstat 和 libmagic。当我通过 sshfs 挂载 NetBSD 文件系统并编译/运行 Linux 代码时,我得到:

Content-encoding: gzip
Content-Type: text/html; charset=utf-8
Last-Modified: Wed, 27 May 2015 01:15:28 GMT

xڭW_o�6/���d�I�8��4��+4-0��E�,������(Я����3�a�&��
;R�#�v�
�X�����~w��Ͽ��%��▒(��wd@���,%,�ڀ�Mã�5�Y[����a�k��4<SyI�H$���B�
�=C{iAs▒S�Riې� n�!��`��"
a��aT°�Mô(�PEC�6IZ�L�mBR��9

�cb�S:u+"���j��0:�c ��ϿSƠr��BwÐ<^jE�4���?��`�����SyL
�-۾m��̘x�9E�_�ũ�\��l����2V夞%���f�
�� F�k}7A��Q���0b y)�����▒!����ހ�h�ߗCR�Ǣ▒��ҥ2`"�D�[B����s������1p�ajz#R"-y���
a*$��ZML0▒ĵ����H߶�&?�z��1�� -8y�Uq\��S�.ΉJ� !��3^8.(y_����G�?����
�M����L���.�Цi�0zu����n�W�Nw������n��-��X v^bJZ���qc%9�� ����^V
��ݾ%:e[
?5Q▒�+▒$��=�9�*�&1�����0�ƺ5�:▒"�*q5��4 L�;D٦U46��H��j�rw�|��PH6���O9�q�U5��k���ޏ���2U6��Y����R ��iS��'��K9)��m�(��V���qf����9՘*���
����y�����@VqɌ)��ո�������%�s��WLo��j�ǯ.p��nW_l���X
P�nK��F0���m.*�k$*$~a���9W�& �s%�6�ö�A�▒�� �.G��oc���
�(���}@▒��L
'K�����z��@�D���l6�$
�0▒�E=@VtB�FW�������:�r�%E�M��mw�)i���;_�^0z �AG+RRYgg˖[)�i�*BFW�I���v��3m���)�駖��i�r.)Cz��+�-������Q~\b\b%V▒u)b۠�-��N�e4Vj��Z
S�`�VW����s�(�.֪z���ܤ���h���Wm�^a0;U9�;�K�`���bR�������a��뇗A�UpMuc6
0<�K�>��Q��pB<��NyyB�*�$<�Ǎ|��'�7XԌ��C(
�}r�|N▒٠� 0[��N�$��y���!�y���4<>L���������|�ݧNQ[�:v���Ng/Xض▒�8
^�h�s���L���Z�����Ѐ�����?ꌲ
1������R�J8���.IL��f���Wv�N��w�&c���-d����%>�_�/��4R®�S�C6a��-�1C��
���^�G�k~q}���Ӎ�V�@� Y�$uo▒Ĺf�4q��
�Ȓ�k���
Xn�'>kn�>[�WO���(P�l�[jZ�R0#�
�>��ͨ�׸-�>�ƶ�H)+����z�S����x,�������p�▒j���ǹ���7Rg]�k~���b��֯[o�[��_���_�F^F

这意味着相同的代码无需任何修改即可在 Linux 上运行。

附加信息:

  • NetBSD 上的 uname -a 返回NetBSD odin 6.1.2 NetBSD 6.1.2 (GENERIC) amd64
  • Linux 上的 uname -a 返回Linux localhost.localdomain 3.16.0-rc7-ck2 #1 SMP Fri May 1 13:38:34 CEST 2015 x86_64 GNU/Linux
  • gcc-4.5.3 是 NetBSD 上的编译器版本
  • gcc-4.9.2 是 Linux 上的编译器版本
  • 两种架构都是相同的,并且两种编译器都使用相同的通用标志,但都禁用了所有优化。

更新

似乎出于未知原因magic_descriptor()正在关闭 NetBSD 上的文件描述符,实际上以下简单代码不起作用:

// test case for a libmagic bug. Libmagic is part of NetBSD packages and is used with the file command
#include <errno.h>
#include <err.h>
#include <magic.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* gcc test.c -o test
./test a_regular_file_with read permissions*/
int main(int argc,char * argv[]) {
int fd=open(argv[1],O_RDONLY); // set fd to 8
struct stat sb;
fstat(fd, &sb);

magic_t mime_type=magic_open(MAGIC_PRESERVE_ATIME|MAGIC_DEVICES|MAGIC_SYMLINK|MAGIC_MIME|MAGIC_COMPRESS);
magic_load(mime_type,NULL); // load default libmagic database
printf("Content-encoding: gzip\nContent-Type: %s\n\r\n",magic_descriptor(mime_type,fd)); // after this fd still ==8 but the file is closed whereas it shouldn’t. And indeed it doesn’t on SUA and Linux distros.
//magic_close(mime_type);

void * HTTP_file=mmap(NULL,sb.st_size,PROT_READ,MAP_SHARED|MAP_FILE,fd,0); // always returns -1
if(HTTP_file==(void *)-1)
err(1,"errno=%d",errno); // errno is equal to 9 which mean the file descriptor is invalid
write(STDOUT_FILENO, HTTP_file, sb.st_size);
}

最佳答案

正如 Google 可以告诉您的那样,这是原始来源中的错误功能/错误:

0000276: magic_descriptor() closes underlying file descriptor (fd) when it finishes

在 5.18 之前的所有 filelibmagic 版本中,您应该将此视为 magic_descriptor() 的已知行为。 IE。不要期望描述符在该调用之后保持打开状态,除非您知道您使用的是更新的版本。

file 的固定版本将包含在 NetBSD 7.0 中——在适当的 NetBSD 邮件列表上温和地催促请求上拉到当前版本分支也可能将其包含在下一个版本中NetBSD-6.x.

关于c - NetBSD 上的 libmagic 关闭文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30617972/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com