Python os.set_inheritable Function
Last modified April 11, 2025
This comprehensive guide explores Python's os.set_inheritable
function,
which controls file descriptor inheritance across process creation. We'll cover
inheritance flags, process management, and practical examples.
Basic Definitions
The os.set_inheritable
function sets the inheritable flag of a
file descriptor. This determines if child processes can inherit the descriptor.
Key parameters: fd (file descriptor), inheritable (boolean flag). Returns None. Available on Unix and Windows systems with different underlying implementations.
Basic Usage Example
This example demonstrates setting a file descriptor as inheritable before spawning a child process. The child process will inherit the open file.
import os # Create a temporary file fd = os.open("test.txt", os.O_RDWR | os.O_CREAT) # Make the file descriptor inheritable os.set_inheritable(fd, True) # Spawn a child process pid = os.fork() if pid == 0: # Child process print(f"Child process with PID {os.getpid()}") os.write(fd, b"Written by child\n") os.close(fd) else: # Parent process print(f"Parent process with PID {os.getpid()}") os.waitpid(pid, 0) # Wait for child os.lseek(fd, 0, os.SEEK_SET) print("File content:", os.read(fd, 100)) os.close(fd) os.unlink("test.txt")
The parent creates a file and sets it as inheritable before forking. Both processes can then write to the same file descriptor.
This demonstrates basic inheritance behavior between parent and child processes.
Preventing Inheritance
This example shows how to prevent a file descriptor from being inherited by child processes. This is useful for security-sensitive file operations.
import os # Open a sensitive file fd = os.open("secret.txt", os.O_RDONLY) # Explicitly prevent inheritance os.set_inheritable(fd, False) # Spawn child process pid = os.fork() if pid == 0: # Child process try: # Attempt to read from the file print(os.read(fd, 100)) except OSError as e: print(f"Child failed to access file: {e}") finally: os._exit(0) else: # Parent process os.waitpid(pid, 0) print("Parent can still read:", os.read(fd, 100)) os.close(fd)
The parent opens a file but prevents inheritance. The child process fails to access the file descriptor while the parent retains access.
This technique helps protect sensitive resources from being accessed by child processes.
Inheritance with Pipes
This example demonstrates inheritance behavior with pipe file descriptors, which are commonly used for inter-process communication.
import os # Create a pipe r, w = os.pipe() # Set read end as inheritable os.set_inheritable(r, True) pid = os.fork() if pid == 0: # Child process os.close(w) # Close write end print("Child received:", os.read(r, 100)) os.close(r) else: # Parent process os.close(r) # Close read end os.write(w, b"Message from parent") os.close(w) os.waitpid(pid, 0)
The parent creates a pipe and sets the read end as inheritable. The child process inherits the read descriptor and can receive data from the parent.
Pipes are a common use case for controlled descriptor inheritance.
Checking Inheritance Status
This example shows how to check the current inheritance status of a file
descriptor using os.get_inheritable
.
import os fd = os.open("temp.txt", os.O_RDWR | os.O_CREAT) # Check default inheritance status print("Default inheritable:", os.get_inheritable(fd)) # Change and verify status os.set_inheritable(fd, True) print("After setting True:", os.get_inheritable(fd)) os.set_inheritable(fd, False) print("After setting False:", os.get_inheritable(fd)) os.close(fd) os.unlink("temp.txt")
The code opens a file and checks its default inheritance status. It then modifies and verifies the status changes.
This demonstrates how to inspect and modify inheritance flags dynamically.
Inheritance with Subprocess
This example shows how file descriptor inheritance works with Python's
subprocess
module.
import os import subprocess # Create a file and make inheritable fd = os.open("output.txt", os.O_RDWR | os.O_CREAT) os.set_inheritable(fd, True) # Launch subprocess with inherited descriptor proc = subprocess.Popen( ["python3", "-c", f"import os; os.write({fd}, b'Written by subprocess\\n')"], pass_fds=[fd] ) proc.wait() # Verify content os.lseek(fd, 0, os.SEEK_SET) print("File content:", os.read(fd, 100)) os.close(fd) os.unlink("output.txt")
The parent process opens a file and explicitly passes it to a subprocess. The subprocess inherits the descriptor and writes to the file.
This demonstrates controlled inheritance with Python's higher-level process API.
Windows-Specific Behavior
This example highlights Windows-specific behavior of set_inheritable
,
where inheritance works differently than on Unix systems.
import os import sys if sys.platform != "win32": print("This example is for Windows only") sys.exit(1) # On Windows, inheritance must be set at creation time import msvcrt fd = os.open("winfile.txt", os.O_RDWR | os.O_CREAT) # Windows requires setting inheritable flag at creation handle = msvcrt.get_osfhandle(fd) print(f"Original handle inheritable: {msvcrt.HANDLE(handle).inheritable}") # Try to modify inheritance (may not work as expected) os.set_inheritable(fd, True) print(f"After set_inheritable: {msvcrt.HANDLE(handle).inheritable}") os.close(fd) os.unlink("winfile.txt")
On Windows, inheritance flags are typically set at handle creation time.
set_inheritable
may have limited effect compared to Unix systems.
This demonstrates important platform differences in descriptor inheritance.
Security Considerations
- Least privilege: Only make necessary descriptors inheritable
- Platform differences: Windows and Unix handle inheritance differently
- Resource leaks: Inherited descriptors must be properly closed
- Race conditions: Set inheritance flags before process creation
- Alternative approaches: Consider higher-level IPC mechanisms
Best Practices
- Explicit control: Always set inheritance flags explicitly
- Cleanup: Ensure proper descriptor cleanup in all processes
- Documentation: Document inheritance requirements clearly
- Testing: Verify behavior on all target platforms
- Alternatives: Consider pipes or sockets for IPC
Source References
Author
List all Python tutorials.