对比windows和linux的对父进程的文件描述符继承的设置
来源:互联网 发布:3cdaemon 端口 编辑:程序博客网 时间:2024/05/17 22:52
需要实现一个fopen中的子进程是否继承父进程的文件句柄的功能。
由于在多平台上,所以需要考虑windows和Linux及类Unix系统。
Linux实现的阻碍:
Linux中是默认子进程能够继承fd的。
1.由于需要在fopen函数中实现,但是看了下关于O_CLOEXEC属性(since Linux 2.6.23)是在open函数中的。
其含义就是在获取新的文件描述符时,使能close-on-exec flag,即使得在调用exec函数集时主动预先关闭父进程的文件描述符。
这在open中是一个Flag,也就是说是一个int型值。
2.正由于open中是一个int型值,而其他的文件属性相关的大部分在fopen都是rw等以char*形式提供的mode。所以出现了不好统一的的情况。
汇集一点:open中提供了对应的int型的flag,但是我们要打开的是文件需要调用fopen,fopen又没有提供int型的设置参数,只有字符串类型的mode作为设置参数。
解决办法:
还是查资料,发现了在glibc中,fopen已经提供了类似的参数在mode中,以字符'e'表示O_CLOEXECflag。但是这里有一个限制,就是必须要是glibc 2.7版本以后才会有这种解析。如果是之前的版本,就只好先用open接口加上O_CLOEXEC的flag做为参数获取到fd,然后再利用fdopen,来进行mode的设置。
windows的实现阻碍:
windows中是默认子进程能够不能继承fd的,因为要提前设置好条件。
其实关键在于,这个实现的有没有意义。因为下面的资料上也有提及,如果要继承父进程的句柄,则需要有两步
1.在创建获取句柄(类似于文件描述符)的时候,就要明确在属性中设置是可以用于子进程继承的。
2.在创建子子进程时,是否允许继承的参数就要设置成true,否则仍然不能继承。
摘自:http://man7.org/linux/man-pages/man3/fopen.3.htm
NAME top
fopen, fdopen, freopen - stream open functions
SYNOPSIS top
#include <stdio.h> FILE *fopen(const char *path, const char *mode); FILE *fdopen(int fd, const char *mode); FILE *freopen(const char *path, const char *mode, FILE *stream); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): fdopen(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
DESCRIPTION top
The fopen() function opens the file whose name is the string pointed to by path and associates a stream with it. The argument mode points to a string beginning with one of the following sequences (possibly followed by additional characters, as described below): r Open text file for reading. The stream is positioned at the beginning of the file. r+ Open for reading and writing. The stream is positioned at the beginning of the file. w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file. a+ Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file. The mode string can also include the letter 'b' either as a last character or as a character between the characters in any of the two- character strings described above. This is strictly for compatibility with C89 and has no effect; the 'b' is ignored on all POSIX conforming systems, including Linux. (Other systems may treat text files and binary files differently, and adding the 'b' may be a good idea if you do I/O to a binary file and expect that your program may be ported to non-UNIX environments.) See NOTES below for details of glibc extensions for mode. Any created files will have mode S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666), as modified by the process's umask value (see umask(2)). Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file positioning function intervene between output and input, unless an input operation encounters end-of-file. (If this condition is not met, then a read is allowed to return the result of writes other than the most recent.) Therefore it is good practice (and indeed sometimes necessary under Linux) to put an fseek(3) or fgetpos(3) operation between write and read operations on such a stream. This operation may be an apparent no-op (as in fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect). Opening a file in append mode (a as the first character of mode) causes all subsequent write operations to this stream to occur at end-of-file, as if preceded the call: fseek(stream, 0, SEEK_END); The fdopen() function associates a stream with the existing file descriptor, fd. The mode of the stream (one of the values "r", "r+", "w", "w+", "a", "a+") must be compatible with the mode of the file descriptor. The file position indicator of the new stream is set to that belonging to fd, and the error and end-of-file indicators are cleared. Modes "w" or "w+" do not cause truncation of the file. The file descriptor is not dup'ed, and will be closed when the stream created by fdopen() is closed. The result of applying fdopen() to a shared memory object is undefined. The freopen() function opens the file whose name is the string pointed to by path and associates the stream pointed to by stream with it. The original stream (if it exists) is closed. The mode argument is used just as in the fopen() function. The primary use of the freopen() function is to change the file associated with a standard text stream (stderr, stdin, or stdout).
RETURN VALUE top
Upon successful completion fopen(), fdopen() and freopen() return a FILE pointer. Otherwise, NULL is returned and errno is set to indicate the error.
NOTES top
Glibc notes The GNU C library allows the following extensions for the string specified in mode: c (since glibc 2.3.3) Do not make the open operation, or subsequent read and write operations, thread cancellation points. This flag is ignored for fdopen(). e (since glibc 2.7) Open the file with the O_CLOEXEC flag. See open(2) for more information. This flag is ignored for fdopen(). m (since glibc 2.3) Attempt to access the file using mmap(2), rather than I/O system calls (read(2), write(2)). Currently, use of mmap(2) is attempted only for a file opened for reading. x Open the file exclusively (like the O_EXCL flag of open(2)). If the file already exists, fopen() fails, and sets errno to EEXIST. This flag is ignored for fdopen(). In addition to the above characters, fopen() and freopen() support the following syntax in mode: ,ccs=string The given string is taken as the name of a coded character set and the stream is marked as wide-oriented. Thereafter, internal conversion functions convert I/O to and from the character set string. If the ,ccs=string syntax is not specified, then the wide- orientation of the stream is determined by the first file operation. If that operation is a wide-character operation, the stream is marked wide-oriented, and functions to convert to the coded character set are loaded.
BUGS top
摘自:https://msdn.microsoft.com/en-us/library/windows/desktop/ms683463(v=vs.85).aspx
Inheritance
A child process can inherit several properties and resources from its parent process. You can also prevent a child process from inheriting properties from its parent process. The following can be inherited:
- Open handles returned by the CreateFile function. This includes handles to files, console input buffers, console screen buffers, named pipes, serial communication devices, and mailslots.
- Open handles to process, thread, mutex, event, semaphore, named-pipe, anonymous-pipe, and file-mapping objects. These are returned by the CreateProcess, CreateThread, CreateMutex, CreateEvent, CreateSemaphore, CreateNamedPipe,CreatePipe, and CreateFileMapping functions, respectively.
- Environment variables.
- The current directory.
- The console, unless the process is detached or a new console is created. A child console process can also inherits the parent's standard handles, as well as access to the input buffer and the active screen buffer.
- The error mode, as set by the SetErrorMode function.
- The process affinity mask.
- The association with a job.
The child process does not inherit the following:
- Priority class.
- Handles returned by LocalAlloc, GlobalAlloc, HeapCreate, and HeapAlloc.
- Pseudo handles, as in the handles returned by the GetCurrentProcess or GetCurrentThread function. These handles are valid only for the calling process.
- DLL module handles returned by the LoadLibrary function.
- GDI or USER handles, such as HBITMAP or HMENU.
Inheriting Handles
A child process can inherit some of its parent's handles, but not inherit others. To cause a handle to be inherited, you must do two things:
- Specify that the handle is to be inherited when you create, open, or duplicate the handle. Creation functions typically use thebInheritHandle member of a SECURITY_ATTRIBUTES structure for this purpose. DuplicateHandle uses the bInheritHandlesparameter.
- Specify that inheritable handles are to be inherited by setting the bInheritHandles parameter to TRUE when calling theCreateProcess function. Additionally, to inherit the standard input, standard output, and standard error handles, the dwFlagsmember of the STARTUPINFO structure must include STARTF_USESTDHANDLES.
An inherited handle refers to the same object in the child process as it does in the parent process. It also has the same value and access privileges. Therefore, when one process changes the state of the object, the change affects both processes. To use a handle, the child process must retrieve the handle value and "know" the object to which it refers. Usually, the parent process communicates this information to the child process through its command line, environment block, or some form of interprocess communication.
The DuplicateHandle function is useful if a process has an inheritable open handle that you do not want to be inherited by the child process. In this case, use DuplicateHandle to open a duplicate of the handle that cannot be inherited, then use theCloseHandle function to close the inheritable handle. You can also use the DuplicateHandle function to open an inheritable duplicate of a handle that cannot be inherited.
Inheriting Environment Variables
A child process inherits the environment variables of its parent process by default. However, CreateProcess enables the parent process to specify a different block of environment variables. For more information, see Environment Variables.
Inheriting the Current Directory
The GetCurrentDirectory function retrieves the current directory of the calling process. A child process inherits the current directory of its parent process by default. However, CreateProcess enables the parent process to specify a different current directory for the child process. To change the current directory of the calling process, use the SetCurrentDirectory function.
- 对比windows和linux的对父进程的文件描述符继承的设置
- Linux子进程继承父进程的文件描述符
- 提高linux对最大进程数和最大打开文件描述符数的限制
- 对比windows和linux的route设置
- 子进程关闭从父进程继承来的文件描述符
- fork 子进程不继承父进程打开的文件描述符
- 父进程和子进程关于数据和文件描述符的继承的理解
- linux 设置进程使用的最大文件描述符的个数
- linux 如何设置进程所能打开的最大文件描述符个数
- Linux的进程------进程的描述和进程的创建
- FILE与文件描述符的对比
- fork子进程时和父进程之间的文件描述符的问题
- linux进程与它的文件描述符
- Linux进程与它的文件描述符
- Linux进程关于文件描述符的数量限制
- Linux进程关于文件描述符的数量限制
- linux下查看进程使用文件描述符的详细信息
- linux对文件描述符的种种限制
- SVN的MKACTIVITY 403 Forbidden 异常处理
- YTU 2918: Shape系列-4
- 我的博客
- document.ready和window.onload的区别
- ZEOSDBO+SQLite+Delphi7不常见异常信息的解决
- 对比windows和linux的对父进程的文件描述符继承的设置
- 2003 - Cann't connect to MySql server on - 'localhost'(10061)
- Android Studio——如何将AndroidStudio的项目提交到Github上
- YTU 2920: Shape系列-7
- 利用getClassLoader().getResource(*).getPath()获取绝对路径时,因为空格不能获取绝对路径的问题
- CentOS6.5下MariaDB日志及事物详解和基本操作语句
- 【JVM系列】Java 虚拟机指令操作码的映射表
- c文件操作-二进制文件读写
- 第1章第2节练习题7 递减输出