
    iKf                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZ ddlZ eed
d          Z	 ddlZn# e$ r dZY nw xY wdgZddgZej        Zej        Zej        Zej        Zeej        gZ dZ!erd Z"nd Z"eri Z#edgz  Zd Zeg dz  Zd Z$d Z%d Z&d Z'd Z( e)ed          rqej*        Z+d Z,d Z* e)ed          r6ej-        Z.d Z/e/Z-e0                    d           e0                    d            e)ed          s e)ed           rddl1Z1ej2        Z3ej4        Z5d! Z6i Z7d" Z8d8d$Z9d% Z2d9d'Z:ddd&e,fd(Z;e0                    d)           e0                    d*           dev rddd&e/fd+Z<e0                    d,           ej=        sjd- Z*dev rd. Z-e0                    d/            e)ed0          r>ej>        Z?ej@        ZAd1 Z>d2 Z@e0                    d0           e0                    d3           n5d4 Z*dev rd5 Z-e0                    d/           neB                    d            ee eC            eez   d67          ZD eE eFeez                       ZGdS ):aQ  
Low-level operating system functions from :mod:`os`.

Cooperative I/O
===============

This module provides cooperative versions of :func:`os.read` and
:func:`os.write`. These functions are *not* monkey-patched; you
must explicitly call them or monkey patch them yourself.

POSIX functions
---------------

On POSIX, non-blocking IO is available.

- :func:`nb_read`
- :func:`nb_write`
- :func:`make_nonblocking`

All Platforms
-------------

On non-POSIX platforms (e.g., Windows), non-blocking IO is not
available. On those platforms (and on POSIX), cooperative IO can
be done with the threadpool.

- :func:`tp_read`
- :func:`tp_write`

Child Processes
===============

The functions :func:`fork` and (on POSIX) :func:`forkpty` and :func:`waitpid` can be used
to manage child processes.

.. warning::

   Forking a process that uses greenlets does not eliminate all non-running
   greenlets. Any that were scheduled in the hub of the forking thread in the parent
   remain scheduled in the child; compare this to how normal threads operate. (This behaviour
   may change is a subsequent major release.)
    )absolute_importN)S_ISREG)_get_hub_noargs)reinit)Event)config)copy_globalsEAGAIN   forktp_readtp_writeTc                 @    t          j         | t           j                  S N)fcntlF_GETFDfds    4/usr/local/lib/python3.11/dist-packages/gevent/os.py_check_fd_validr   Q   s     {2u}---    c                     d S r    r   s    r   r   r   V   s	     	r   closec                    t          |            t          |           }t          |j                  rt          rt          |           S t                      }|j        }| t          v rt          	                    | d          V|
                                5 }|                    |           ddd           n# 1 swxY w Y                       d           t          t          j                  |                    |            |                                t#                      t          | <   fd}                    ||            dS )a  
        Close a file descriptor.

        This function cooperates with gevent to avoid crashing
        the process if you (accidentally) call it while you're
        still performing IO on the file descriptor; for example, if you have it
        registered with a ``Selector`` implementation, which documents
        that you *must* unregister FDs before closing them.

        If the *fd* refers to a regular file, this cooperation is *not*
        used. This is because trying to use gevent to poll on regular
        files doesn't work and shouldn't be done. We assume that everyone
        is following the rules.

        .. caution::
           This function is not intended for use on Windows.

        .. versionadded:: 25.8.1
        NgMbP?c                    	 t          |            n# t          $ r Y nw xY w                                 t                              | d                                                                              d S #                                  t                              | d                                                                              w xY wr   )_closeOSErrorset_closing_fd_to_eventpopstopr   )r   checkevents    r   cbzclose.<locals>.cb   s    r



    		$((T222

 		$((T222

s"    A< 
 A<  A< <AC)r   _fstatr   st_mode_NO_DEFER_REG_FILEr   get_hubloopr    r!   idlewaitr   errnoEBADF
closing_fdr#   r   start)r   statshubr*   watcherr%   r#   r$   s         @@r   r   r   `   s   F 	r

5=!! 	&8 	"::iix%%% ),,R66E  YY[[ &GHHW%%%& & & & & & & & & & & & & & & 

5!!! %+&&& 	

#(R 	 	 	 	 	 	 	Bs   B<<C C )make_nonblockingnb_readnb_writec                     t          j         | t           j        d          }t          |t          j        z            s/t          j         | t           j        |t          j        z             dS dS )zPut the file descriptor *fd* into non-blocking mode if
        possible.

        :return: A boolean value that evaluates to True if successful.
        r   TN)r   F_GETFLboolos
O_NONBLOCKF_SETFL)r   flagss     r   r4   r4      s\     Bq11EBM)** 	KEM52=+@AAA4	 	r   c                 v   d}d}	 	 	 t          | |          }|||                                 d}d}S S # t          $ r}|j        t          vr Y d}~nd}~ww xY w|)t                      }|j                            | d          }|                    |           # ||                                 d}d}w xY w)a  
        Read up to *n* bytes from file descriptor *fd*. Return a
        byte string containing the bytes read, which may be shorter than
        *n*. If end-of-file is reached, an empty string is returned.

        The descriptor must be in non-blocking mode.
        N   )	_readr   r   r-   ignored_errorsr)   r*   ior,   )r   nr2   r$   resultes         r   r5   r5      s     	
 "2q\\F!   !    wn44 54444 ;!))CHKKA..E
   



,   B 5 
AAB AAB B8c                 v   d}d}	 	 	 t          | |          }|||                                 d}d}S S # t          $ r}|j        t          vr Y d}~nd}~ww xY w|)t                      }|j                            | d          }|                    |           # ||                                 d}d}w xY w)z
        Write some number of bytes from buffer *buf* to file
        descriptor *fd*. Return the number of bytes written, which may
        be less than the length of *buf*.

        The file descriptor must be in non-blocking mode.
        Nr?      )	_writer   r   r-   rA   r)   r*   rB   r,   )r   bufr2   r$   rD   rE   s         r   r6   r6      s     	
 #B__F!   !    wn44 54444 ;!))CHKKA..E
   



rF   c                 ^    t                      j                            t          | |f          S )zRead up to *n* bytes from file descriptor *fd*. Return a string
    containing the bytes read. If end-of-file is reached, an empty string
    is returned.

    Reading is done using the threadpool.
    )r)   
threadpoolapplyr@   )r   rC   s     r   r   r     s%     99%%eb!W555r   c                 ^    t                      j                            t          | |f          S )zWrite bytes from buffer *buf* to file descriptor *fd*. Return the
    number of bytes written.

    Writing is done using the threadpool.
    )r)   rL   rM   rI   )r   rJ   s     r   r   r     s%     99%%fr3i888r   c                      ddl } |                                 5  |                     dt                     t	                      }ddd           n# 1 swxY w Y   |st                       |S )a  
        Forks the process using :func:`os.fork` and prepares the
        child process to continue using gevent before returning.

        .. note::

            The PID returned by this function may not be waitable with
            either the original :func:`os.waitpid` or this module's
            :func:`waitpid` and it may not generate SIGCHLD signals if
            libev child watchers are or ever have been in use. For
            example, the :mod:`gevent.subprocess` module uses libev
            child watchers (which parts of gevent use libev child
            watchers is subject to change at any time). Most
            applications should use :func:`fork_and_watch`, which is
            monkey-patched as the default replacement for
            :func:`os.fork` and implements the ``fork`` function of
            this module by default, unless the environment variable
            ``GEVENT_NOWAITPID`` is defined before this module is
            imported.

        .. versionadded:: 1.1b2
        r   Nignore)warningscatch_warningssimplefilterDeprecationWarning	_raw_forkr   )rQ   rD   s     r   fork_geventrV   '  s    . 	 $$&& 	! 	!!!(,>???[[F	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	!  	HHHs   *AAAc                      t                      S )zL
        A wrapper for :func:`fork_gevent` for non-POSIX platforms.
        rV   r   r   r   r   r   H  s     }}r   forkptyc                  L    t                      \  } }| st                       | |fS )a  
            Forks the process using :func:`os.forkpty` and prepares the
            child process to continue using gevent before returning.

            Returns a tuple (pid, master_fd). The `master_fd` is *not* put into
            non-blocking mode.

            Availability: Some Unix systems.

            .. seealso:: This function has the same limitations as :func:`fork_gevent`.

            .. versionadded:: 1.1b5
            )_raw_forkptyr   )pid	master_fds     r   forkpty_geventr^   Q  s,     *^^NC 	>!r   r^   WNOWAITWNOHANGc                      d S r   r   r   r   r   <lambda>rb   q  s     r   c                 6   |                                   	 | j        | j        t          j                    ft          | j        <   |r ||            t                       t                       |                                  d S # |                                  w xY wr   )r"   r\   rstatustime_watched_children_on_child_hook_reap_childrenr   )r3   callbacks     r   	_on_childrj   v  s     LLNNN	 29+wPTPYP[P[1\!'+. &HW%%%      s   AB B<   c                     t          j                     }|| z
  fdt                                          D             }|D ]
}t          |= d S )Nc                 \    g | ](\  }}t          |t                    r|d          k     &|)S )rH   )
isinstancetuple).0r\   valoldest_alloweds      r   
<listcomp>z"_reap_children.<locals>.<listcomp>  sJ        Sc5)) /2!f~.E.E .E.E.Er   )re   rf   items)timeoutnowdeadr\   rr   s       @r   rh   rh     ss      )++C 7]N   $**,,  D
  + +%c**+ +r   c                    | dk    r| dk    rNd}t                                           D ]2\  }}t          |t                    r||d         |k     r
|} |d         }3| dk    r| dk    rj|dk    rdt	                      }|j                            dd          5 }|                    |           |j        |j	        fcddd           S # 1 swxY w Y   t          | |          S | t           v r|t          z  s t          t           |          t                    r6t           |          }t          |t                    rt           | = |dd         S dS t           |          }|j                            | d          5 }t	                                          |           ddd           n# 1 swxY w Y   |j        |j	        fS t          | |          S )a  
            Wait for a child process to finish.

            If the child process was spawned using
            :func:`fork_and_watch`, then this function behaves
            cooperatively. If not, it *may* have race conditions; see
            :func:`fork_gevent` for more information.

            The arguments are as for the underlying
            :func:`os.waitpid`. Some combinations of *options* may not
            be supported cooperatively (as of 1.1 that includes
            WUNTRACED). Using a *pid* of 0 to request waiting on only processes
            from the current process group is not cooperative. A *pid* of -1
            to wait for any child is non-blocking, but may or may not
            require a trip around the event loop, depending on whether any children
            have already terminated but not been waited on.

            Availability: POSIX.

            .. versionadded:: 1.1b1
            .. versionchanged:: 1.2a1
               More cases are handled in a cooperative manner.
            r   NrH   F)r   r   )rf   rt   rn   ro   r)   r*   childr,   rpidrd   _waitpid_WNOHANG)	r\   optionsfinished_atkvr2   r3   rD   new_watchers	            r   waitpidr     sc   B axx"99
 #'K 1 7 7 9 9 / /1 *1e 4 4/%0%8AaD;<N<N"#C*+A$K!88 byyW\\%ii X^^Au55 AHHW---#*<#@A A A A A A A A A A A A A A A A $C111''' X% 
"4Ec4JE)R)R 
" /s3F!&%00 * .c2%bqbz)!6 ,C0 \''U33 0{IINN;///0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |W_44 C)))s$   #CC
C
2"F  F$'F$Fc                     |pt                      j        }|                    | |          }|t          | <   |                    t
          ||           d S )N)ref)r)   r*   rz   rf   r0   rj   )r\   ri   r*   r   r3   s        r   _watch_childr     sN    )799>Djj#j..G%,c"MM)Wh77777r   c                 B     |            }|rt          || ||           |S )a  
            Fork a child process and start a child watcher for it in the parent process.

            This call cooperates with :func:`waitpid` to enable cooperatively waiting
            for children to finish. When monkey-patching, these functions are patched in as
            :func:`os.fork` and :func:`os.waitpid`, respectively.

            In the child process, this function calls :func:`gevent.hub.reinit` before returning.

            Availability: POSIX.

            :keyword callback: If given, a callable that will be called with the child watcher
                when the child finishes.
            :keyword loop: The loop to start the watcher in. Defaults to the
                loop of the current hub.
            :keyword fork: The fork function. Defaults to :func:`the one defined in this
                module <gevent.os.fork_gevent>` (which automatically calls :func:`gevent.hub.reinit`).
                Pass the builtin :func:`os.fork` function if you do not need to
                initialize gevent in the child process.

            .. versionadded:: 1.1b1
            .. seealso::
                :func:`gevent.monkey.get_original` To access the builtin :func:`os.fork`.
            )r   )ri   r*   r   r   r\   s        r   fork_and_watchr     s0    2 $&&C 7S(D#666Jr   r   rV   c                 J    g fd}t          | |||           d         S )z
                Like :func:`fork_and_watch`, except using :func:`forkpty_gevent`.

                Availability: Some Unix systems.

                .. versionadded:: 1.1b5
                c                  R                 }                      |            | d         S )Nr   )append)
pid_and_fdrY   rD   s    r   _forkz forkpty_and_watch.<locals>._forkB  s*    !(JMM*---%a=(r   r   r   )ri   r*   r   rY   r   rD   s      ` @r   forkpty_and_watchr   8  sI     ) ) ) ) ) ) xsE:::ay r   r   c                      t          | i |S )a  
                Forks a child process and starts a child watcher for it in the
                parent process so that ``waitpid`` and SIGCHLD work as expected.

                This implementation of ``fork`` is a wrapper for :func:`fork_and_watch`
                when the environment variable ``GEVENT_NOWAITPID`` is *not* defined.
                This is the default and should be used by most applications.

                .. versionchanged:: 1.1b2
                r   argskwargss     r   r   r   O  s     &t6v666r   c                      t          | i |S )a  
                    Like :func:`fork`, but using :func:`forkpty_gevent`.

                    This implementation of ``forkpty`` is a wrapper for :func:`forkpty_and_watch`
                    when the environment variable ``GEVENT_NOWAITPID`` is *not* defined.
                    This is the default and should be used by most applications.

                    .. versionadded:: 1.1b5
                    )r   r   s     r   rY   rY   ^  s     -d=f===r   r   posix_spawnc                  <    t          | i |}t          |           |S r   )_raw_posix_spawnr   r   r   r\   s      r   r   r   p  s'    *D;F;;C %%%Jr   c                  <    t          | i |}t          |           |S r   )_raw_posix_spawnpr   r   s      r   posix_spawnpr   u  s'    +T<V<<C %%%Jr   r   c                      t                      S )a  
                Forks a child process, initializes gevent in the child,
                but *does not* prepare the parent to wait for the child or receive SIGCHLD.

                This implementation of ``fork`` is a wrapper for :func:`fork_gevent`
                when the environment variable ``GEVENT_NOWAITPID`` *is* defined.
                This is not recommended for most applications.
                rX   r   r   r   r   r   }  s     #}}$r   c                      t                      S )a~  
                    Like :func:`fork`, but using :func:`os.forkpty`

                    This implementation of ``forkpty`` is a wrapper for :func:`forkpty_gevent`
                    when the environment variable ``GEVENT_NOWAITPID`` *is* defined.
                    This is not recommended for most applications.

                    .. versionadded:: 1.1b5
                    )r^   r   r   r   rY   rY     s     *+++r   r   )names_to_ignoredunder_names_to_keep)rk   )NNF)H__doc__
__future__r   r:   statr   
gevent.hubr   r)   r   gevent.eventr   gevent._configr   gevent._utilr	   r-   getattrr
   r   ImportError__implements____extensions__readr@   writerI   r   r   fstatr&   EINTRrA   r(   r   r    r4   r5   r6   r   r   hasattrr   rU   rV   rY   r[   r^   r   re   r   r|   r`   r}   rg   rf   rj   rh   r   r   r   disable_watch_childrenr   r   r   r   removeglobals__imports__listr   __all__r   r   r   <module>r      s  ) )V ' & & & & & 				       1 1 1 1 1 1             ! ! ! ! ! ! % % % % % % 	"	%	%LLLL   EEE Z(
			 %+&   
. . . .
   	 pwj Ne e eP BBBBN	 	 	  :  :6 6 69 9 9 72v u" I  B   wr9 0z	" 	" 	"& !i(((.///wr9 k-Y!7!7 k-:: & 	  	  	 	+ 	+ 	+ 	+4n	* n	* n	*`	8 	8 	8 	8 %)t[ 	 	 	 	> 	.///m,,,&&+/d~ ! ! ! !" !!"5666 , H	-7 7 7 N**> > > !!),,,wr=)) 6#%> $&O!  
  
 %%m444%%n555	% 	% 	% N**
, 
, 
, !!),,, &!!! l2wwyy+9N+J024 4 4 $ss>N233
4
4s   A AA