o
    e|P                     @   s  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Zeedd	ZzddlZW n ey?   dZY nw d
gZddgZejZejZeejgZerfeg d7 Zdd Zdd Zdd Zdd Zdd Zeed
r0ejZ dd Z!dd
 Zeedrej"Z#dd Z$e$Z"e%d e%d eedseedr/ddl&Z&ej'Z(ej)Z*dd Z+i Z,d d! Z-d8d#d$Z.d%d& Z'd9d(d)Z/ddd'e!fd*d+Z0e%d+ e%d dev rddd'e$fd,d-Z1e%d- e	j2sd.d
 Zdev rd/d Z"e%d& eed0rej3Z4ej5Z6d1d0 Z3d2d3 Z5e%d0 e%d3 nd4d
 Zdev r*d5d Z"e%d& ne7d
 eee8 ee d6d7Z9e:e;ee Z<d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)_get_hub_noargs)reinit)config)copy_globalsEAGAIN   forktp_readtp_write)make_nonblockingnb_readnb_writec                 C   s<   t  | t jd}t|tj@ st  | t j|tjB  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)fcntlZF_GETFLboolosZ
O_NONBLOCKZF_SETFL)fdflags r   9D:\Projects\ConvertPro\env\Lib\site-packages\gevent/os.pyr   K   s
   r   c              
   C   s   d}d}zD	 zt | |}|W W |dur|  d}d}S S  ty4 } z|jtvr* W Y d}~nd}~ww |du rCt }|j| d}|| q|durU|  d}d}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   )	_readcloseOSErrorerrnoignored_errorsget_hubloopiowait)r   nhubeventresulter   r   r   r   V   6   
	

r   c              
   C   s   d}d}zD	 zt | |}|W W |dur|  d}d}S S  ty4 } z|jtvr* W Y d}~nd}~ww |du rCt }|j| d}|| q|durU|  d}d}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   r   r   r   r   r   )r   bufr!   r"   r#   r$   r   r   r   r   s   r%   r   c                 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   r    r   r   r   r
      s   c                 C   r)   )zWrite bytes from buffer *buf* to file descriptor *fd*. Return the
    number of bytes written.

    Writing is done using the threadpool.
    )r   r*   r+   r'   )r   r(   r   r   r   r      s   c                  C   s   t  } | 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
        )	_raw_forkr   )r#   r   r   r   fork_gevent   s   r-   c                   C      t  S )zL
        A wrapper for :func:`fork_gevent` for non-POSIX platforms.
        r-   r   r   r   r   r	      s   forkptyc                  C   s   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   )pidZ	master_fdr   r   r   forkpty_gevent   s   
r3   ZWNOWAITWNOHANGc                   C   s   d S Nr   r   r   r   r   <lambda>   s    r6   c                 C   sR   |    z| j| jt ft| j< |r||  t  t  W |   d S |   w r5   )stopr2   rstatustime_watched_children_on_child_hook_reap_childrenr   )watchercallbackr   r   r   	_on_child   s   r?   <   c                    s:   t   }||    fddt D }|D ]}t|= qd S )Nc                    s*   g | ]\}}t |tr|d   k r|qS )r&   )
isinstancetuple).0r2   valZoldest_allowedr   r   
<listcomp>  s    z"_reap_children.<locals>.<listcomp>)r9   r:   items)timeoutnowZdeadr2   r   rE   r   r<     s   
r<   c           	      C   sZ  | dkr^| dkr(d}t  D ]\}}t|tr'|du s!|d |k r'|} |d }q| dkr^| dkrY|dkrYt }|jdd}|| |j|j	fW  d   S 1 sTw   Y  t
| |S | t v r|t@ smtt |  trt |  }t|trt | = |dd S dS t |  }|j| d}t | W d   n1 sw   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   Nr&   F)r   r   )r:   rG   rA   rB   r   r   childr   Zrpidr8   _waitpid_WNOHANG)	r2   optionsZfinished_atkvr!   r=   r#   Znew_watcherr   r   r   waitpid  s>   !

 

	

rQ   Fc                 C   s4   |pt  j}|j| |d}|t| < |t|| d S )N)ref)r   r   rK   r:   startr?   )r2   r>   r   rR   r=   r   r   r   _watch_child  s   rT   c                 C   s   | }|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`.
            )rT   )r>   r   rR   r	   r2   r   r   r   fork_and_watch  s   rU   c                    s(   g  fdd}t | ||| d S )z
                Like :func:`fork_and_watch`, except using :func:`forkpty_gevent`.

                Availability: Some Unix systems.

                .. versionadded:: 1.1b5
                c                     s     }  |  | d S )Nr   )append)Z
pid_and_fdr0   r#   r   r   _fork  s   
z forkpty_and_watch.<locals>._forkr   rU   )r>   r   rR   r0   rX   r   rW   r   forkpty_and_watch  s   rZ   c                  O      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
                rY   argskwargsr   r   r   r	     s   c                  O   r[   )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
                    )rZ   r\   r   r   r   r0     s   posix_spawnc                  O      t | i |}t| |S r5   )_raw_posix_spawnrT   r]   r^   r2   r   r   r   r_        c                  O   r`   r5   )_raw_posix_spawnprT   rb   r   r   r   posix_spawnp  rc   re   c                   C   r.   )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.
                r/   r   r   r   r   r	     s   	c                   C   r.   )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
                    )r3   r   r   r   r   r0     s   
r   )Znames_to_ignoreZdunder_names_to_keep)r@   )NNF)=__doc__
__future__r   r   Z
gevent.hubr   r   r   Zgevent._configr   Zgevent._utilr   r   getattrr   r   ImportErrorZ__implements__Z__extensions__readr   writer'   ZEINTRr   r   r   r   r
   r   hasattrr	   r,   r-   r0   r1   r3   rV   r9   rQ   rL   r4   rM   r;   r:   r?   r<   rT   rU   rZ   Zdisable_watch_childrenr_   ra   re   rd   removeglobalsZ__imports__listset__all__r   r   r   r   <module>   s    +

	




p








