dear developer,
I had a traceback, as follows
Traceback (most recent call last): File "/home/rsyncd/post_backup", line 106, in <module> with daemon.DaemonContext(working_directory=here, stdout=out, stderr=out): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/daemon/daemon.py", line 249, in __init__ detach_process = is_detach_process_context_required() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/daemon/daemon.py", line 817, in is_detach_process_context_required if is_process_started_by_init() or is_process_started_by_superserver(): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/daemon/daemon.py", line 795, in is_process_started_by_superserver if is_socket_file(sys.__stdin__): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/daemon/daemon.py", line 759, in is_socket_file file_fd = file.fileno() ^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'fileno'
I solved it with this patch
--- /usr/lib/python3/dist-packages/daemon/daemon.py~ 2022-07-19 02:18:18.000000000 +0000 +++ /usr/lib/python3/dist-packages/daemon/daemon.py 2024-02-18 19:53:32.055404205 +0000 @@ -757,9 +757,9 @@ try: file_fd = file.fileno() - except ValueError: + except (ValueError, AttributeError): # The file doesn't have a file descriptor. - file_fd = None + return False try: file_socket = socket.fromfd(file_fd, socket.AF_INET, socket.SOCK_RAW)
regards
Howdy Andrea,
On 18-Feb-2024, Andrea Mennucci wrote:
What led to this? It seems that sys.__stdin__ is the None object; how did this happen?
sys.__stdin__
None
AttributeError: 'NoneType' object has no attribute 'fileno'
This seems like the correct behaviour when this unusual circumstance happens; the program is in a very unusual state (the sys.__stdin__ should never be modified from its original value), and crashing with a message to inform of this, seems appropriate.
--=20 \ =E2=80=9CSome mornings, it's just not worth chewing through the leat= her | `\ straps.=E2=80=9D =E2=80=94= Emo Philips | _o__) | Ben Finney ben@benfinney.id.au
according to the documentation https://docs.python.org/3/library/sys.html#sys.stdout
Note: Under some conditions stdin, stdout and stderr as well as the original values stdin, stdout and stderr can be None.
here is a code that (on Ubuntu 22.04) will get sys.stdin=None
save this as "first.py"
#!/usr/bin/python3 import sys, os os.close(sys.stdin.fileno()) print('first exec second') os.execvp(os.path.abspath('second.py'), ['second.py'])
save this as "second.py"
#!/usr/bin/python3 import sys print('second running') print('stdin is ', sys.stdin)
output
first exec second second running stdin is None
now if you add
out = open('/tmp/daemon.log', 'a') with daemon.DaemonContext(working_directory='/tmp', stdout=out, stderr=out): print('daemon OK')
at the end of "second.py", you get a traceback from "daemon" code
ignore the patch in my first post... yes no traceback happens, ... but the code in the DaemonContext is not executed
currently I prepend the call to daemon with the following snippet
daemon
if sys.stdin is None: O = open(os.devnull) sys.stdin = sys.__stdin__ = O try: os.stat(0) except OSError: os.dup2(O.fileno, 0)
maybe this code may be integrated into daemon