This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: os.dup seems broken with execvp (LINUX)
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: krsna, martin.panter
Priority: normal Keywords:

Created on 2020-04-16 08:58 by krsna, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg366587 - (view) Author: (krsna) Date: 2020-04-16 08:58
---CODE---
import os
path = "file.txt"
  
fd = os.open(path, os.O_WRONLY) 
  
os.close(1) #STDOUT
os.dup(fd)
pid = os.fork()

if pid == 0:
    args = "ls -l".split() 
    os.execvp(args[0], args)
else:
    os.waitpid(pid, 0)
    print('Done from Parent')
--- END CODE ---

Running this with python
```
> python -V
Python 3.8.2
```
I get the following:
```
> echo"" > file.txt && python example.py && cat file.txt 
ls: write error: Bad file descriptor
Done from Parent

```
Running the same with micropython:
```
> echo"">file.txt && micropython me && cat file.txt 
total 76
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Desktop
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Documents
drwxr-xr-x 2 user user  4096 Apr 13 18:22 Downloads
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Music
drwxr-xr-x 2 user user  4096 Apr 12 11:16 Pictures
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Public
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Templates
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Videos
-rw-rw-r-- 1 user user   244 Apr 15 22:02 example.py
Done from Parent
```
With the follow C which is almost a 1:1 to the CODE segment above
```
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
    int fd = open("file.txt", O_WRONLY);

	close(1);
	dup(fd);
	
    if (fork() == 0) {
    	char *cmd = "ls";
		char *argv[3];
		argv[0] = "ls";
		argv[1] = "-l";
		argv[2] = NULL;
  		execvp(cmd, argv);
	} else {
  		wait(0);
  		close(fd);

	    puts("Done from Parent");
	}

    return 0;
}
```
I get the same output as micropython example above
```
> echo"">file.txt && gcc ccc.c && ./a.out && cat file.txt 
total 76
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Desktop
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Documents
drwxr-xr-x 2 user user  4096 Apr 13 18:22 Downloads
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Music
drwxr-xr-x 2 user user  4096 Apr 12 11:16 Pictures
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Public
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Templates
drwxr-xr-x 2 user user  4096 Apr  5 15:29 Videos
-rwxrwxr-x 1 user user 18904 Apr 15 22:53 a.out
-rw-rw-r-- 1 user user   395 Apr 15 22:50 ccc.c
-rw-rw-r-- 1 user user   244 Apr 15 22:02 example.py
Done from Parent
```
I tried looking around for the code of `dup` in cpython to compare, but could only find `dup2.c`.
msg366591 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2020-04-16 10:13
The file descriptor created by "os.dup" is not inherited by child processes by default since Python 3.4.
https://docs.python.org/3/library/os.html#os.dup

Does it work if you use "os.set_inheritable" or "os.dup2" (which apparently sets it inhertiable by default)?
msg366614 - (view) Author: (krsna) Date: 2020-04-16 17:57
I should read the updated documentation changes to modules more often. Adding the inheritable works and yes I tested with `os.dup2` which seemed consistent with C's dups2. I still think it is quite odd that the low level `dup` function has a different behavior than one would expect.

Thank you for you helpful and quick reply Martin.

This may be closed as it is a documented, imo, misbehavior.

On Thursday, April 16, 2020, 12:13:58 AM HST, Martin Panter <report@bugs.python.org> wrote: 

Martin Panter <vadmium+py@gmail.com> added the comment:

The file descriptor created by "os.dup" is not inherited by child processes by default since Python 3.4.
https://docs.python.org/3/library/os.html#os.dup

Does it work if you use "os.set_inheritable" or "os.dup2" (which apparently sets it inhertiable by default)?

----------
nosy: +martin.panter

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue40299>
_______________________________________
msg366615 - (view) Author: (krsna) Date: 2020-04-16 18:05
Closing has behavior is documented "The file descriptor created by "os.dup" is not inherited by child processes by default since Python 3.4.
https://docs.python.org/3/library/os.html#os.dup"
History
Date User Action Args
2022-04-11 14:59:29adminsetgithub: 84479
2020-04-16 18:05:07krsnasetstatus: open -> closed
resolution: not a bug
messages: + msg366615

stage: resolved
2020-04-16 17:57:34krsnasetmessages: + msg366614
2020-04-16 10:13:40martin.pantersetnosy: + martin.panter
messages: + msg366591
2020-04-16 08:58:09krsnacreate