用它自己的文件复制文件描述符偏移 [英] Duplicate file descriptor with its own file offset

查看:150
本文介绍了用它自己的文件复制文件描述符偏移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

人们如何可以创建从现有文件描述符一个新的文件描述符,使得新的描述符不共享在文件表中的相同的内部文件结构/条目?具体属性,如文件偏移量(和preferably权限,共享和模式)新老文件描述符之间不应该​​被共享。

How can one create a new file descriptor from an existing file descriptor such that the new descriptor does not share the same internal file structure/entry in the file table? Specifically attributes such as file offset (and preferably permissions, sharing and modes) should not be shared between the new and old file descriptors.

在Windows和Linux, DUP()将复制的文件描述符,但双方仍描述指向在进程的文件表相同的文件结构。任何寻求在任描述将调整为其他描述的位置为好。

Under both Windows and Linux, dup() will duplicate the file descriptor, but both descriptors still point to the same file structure in the process' file table. Any seeking on either descriptor will adjust the position for the other descriptors as well.

注意

我因为对Windows和Linux都收到答案已经和调整的问题有点过于频繁,这使得人们很难回答的问题。我会调整我的票,接受它涵盖了Windows的的Linux的最干净的答案。向大家致歉,我还是新来的SO范例。感谢伟大的答案!

I've since received answers for both Windows and Linux and adjusted the question a little too often, which has made it difficult for people to answer. I'll adjust my votes and accept the cleanest answer which covers both Windows and Linux. Apologies to all, I'm still new to the SO paradigm. Thanks for the great answers!

推荐答案

所以基本上,你真正想要的是得到一个文件描述符,基本上打开相同的文件一次又一次,以获得独立的地位,分享,模式等你想这样做,在Windows上(这里的文件描述符基本上是一个异物,而不是由OS直接使用的东西的的运行时库都没有。

So basically, what you really want is to be given a file descriptor, and basically open the same file over again, to get a separate position, sharing, mode, etc. And you want to do this on Windows (where the "file descriptor" is basically a foreign object, not something used directly by the OS or the run-time library at all.

令人吃惊的是,有的一种方式来做到这一点,至少与MS VC ++。这一切,但两个步骤只使用Win32 API的所以移植到其他的编译器/库应该是相当合理的(我认为这两个功能最供给版本)。这些都是对于Unix风格的文件描述符转换到本机Win32文件句柄,并转换成一个原生Win32文件处​​理回Unix风格的文件描述符。

Amazingly enough, there is a way to do that, at least with MS VC++. All but two steps of it use only the Win32 API so porting to other compilers/libraries should be fairly reasonable (I think most supply versions of those two functions). Those are for converting a Unix-style file descriptor to a native Win32 file handle, and converting a native Win32 file handle back to a Unix-style file descriptor.

  1. 转换文件描述到本机文件句柄与_get_osfhandle()

  2. 与GetFileInformationByHandleEx(FILE_NAME_INFO)文件获取的名称 1

  3. 使用CreateFile打开一个新的句柄文件

  4. 与_open_osfhandle该句柄创建一个文件描述符()

的Et瞧的,我们有一个新的文件描述符指同一文件,但与它自己的权限,位置等

Et voilà, we have a new file descriptor referring to the same file, but with its own permissions, position, etc.

对你的问题的最后,你使它听起来像是你也想在权限,但似乎并没有做出任何真正意义上的 - 权限附加到文件本身,而不是该文件是怎么打开,所以打开或重新打开文件,对文件的权限没有影响。如果你真的想知道,你可以用GetFileInformationByHandle得到它,但要知道,在Windows文件权限是在Unix下(传统)文件权限有点不同。 Unix有上的所有文件所有者/组/世界的权限,而且大多数系统也有ACL的(虽然有一个在他们的工作更多的变化)。窗户或者具有根本没有权限(例如,在FAT或FAT32文件)或其他人使用访问控制列表(例如,在NTFS文件),但没有这真的等同于传统的所有者/组/世界权限大多数人都习惯于在Unix。

Toward the end of your question, you make it sound like you also want the "permissions", but that doesn't seem to make any real sense -- the permissions attach to the file itself, not to how the file is opened, so opening or reopening the file has no effect on the file's permissions. If you really want to know the, you can get it with GetFileInformationByHandle, but be aware that file permissions in Windows are quite a bit different from the (traditional) file permissions in Unix. Unix has owner/group/world permissions on all files, and most systems also have ACLs (though there's more variation in how they work). Windows either has no permissions at all (e.g., files on FAT or FAT32) or else uses ACLs (e.g., files on NTFS), but nothing that's really equivalent to the traditional owner/group/world permissions most people are accustomed to on Unix.

也许你正在使用权限来指该文件是否被打开阅读,写作,或两者兼而有之。获得比任何preceding的相当丑陋。问题是,大部分是在图书馆,没有的Win32,所以可能没有办法做到这一点,这将是甚至接近便携编译器之间。随着MS VC ++ 9.0 SP1(无法保证的任何的其他编译器),你可以这样做:

Perhaps you're using "permissions" to refer to whether the file was open for reading, writing, or both. Getting that is considerably uglier than any of the preceding. The problem is that most of it is in the library, not Win32, so there's probably no way to do it that will be even close to portable between compilers. With MS VC++ 9.0 SP1 (not guaranteed for any other compiler) you can do this:

#include <stdio.h>

int get_perms(int fd) {
    int i;
 FILE * base = __iob_func();

    for (i=0; i<_IOB_ENTRIES; i++) 
        if (base[i]._file == fd)
            return base[i]._flag;     // we've found our file
    return 0; // file wasn't found.
}

由于这涉及到一些洞穴探险,我写了一个快速测试,以验证它可能实际工作:

Since this involved some spelunking, I wrote a quick test to verify that it might actually work:

#ifdef TEST
#include <io.h>

void show_perms(int perms, char const *caption) { 
 printf("File opened for %s\n", caption);
 printf("Read permission = %d\n", (perms & _IOREAD)!=0);
 printf("Write permission = %d\n", (perms & _IOWRT)!=0);
}

int main(int argc, char **argv) { 
 FILE *file1, *file2;
 int perms1, perms2;

 file1=fopen(argv[1], "w");
 perms1 = get_perms(_fileno(file1));
 fclose(file1);

 file2=fopen(argv[1], "r");
 perms2 = get_perms(_fileno(file2));
 fclose(file2);

 show_perms(perms1, "writing");
 show_perms(perms2, "reading");
 return 0;
}
#endif

和结果似乎表明成功:

File opened for writing
Read permission = 0
Write permission = 1
File opened for reading
Read permission = 1
Write permission = 0

您可以那么返回的标志对_IOREAD,_IOWRT和_IORW测试,这是在stdio.h中定义。尽管我的previous警告,我也许应该指出的是,我怀疑(虽然我肯定不能保证),该库的这个部分是相当稳定,因此发生重大变化的真正的机会可能是相当小的。

You can then test that returned flag against _IOREAD, _IOWRT, and _IORW, which are defined in stdio.h. Despite my previous warnings, I should probably point out that I suspect (though I certainly can't guarantee) that this part of the library is fairly stable, so the real chances of major changes are probably fairly minimal.

在其他方向,然而,基本上没有机会的所有的,它会与任何其他库工作。它的可能的(但肯定不能保证)与使用MS库中的其他编译器,使用MS VC ++作为后端,如英特尔,MinGW的或科莫工作。其中,我会说最有可能的合作会是科莫,而最不可能MinGW的(但是这只是一种猜测,有一个很好的机会,它不会与任何人合作)

In the other direction, however, there's basically no chance at all that it'll work with any other library. It could (but certainly isn't guaranteed to) work with the other compilers that use the MS library, such as Intel, MinGW or Comeau using MS VC++ as its back-end. Of those, I'd say the most likely to work would be Comeau, and the least likely MinGW (but that's only a guess; there's a good chance it won't work with any of them).


  1. 需要可再发行的<一个href=\"http://www.microsoft.com/downloads/details.aspx?FamilyId=1DECC547-AB00-4963-A360-E4130EC079B8&displaylang=en\">Win32写到FileID API库

  1. Requires the redistributable Win32 FileID API Library

这篇关于用它自己的文件复制文件描述符偏移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆