1 #ifndef LIBSSH2_SESSION_H
2 #define LIBSSH2_SESSION_H
3 /* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
4  * Copyright (c) 2009-2010 by Daniel Stenberg
5  * Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms,
9  * with or without modification, are permitted provided
10  * that the following conditions are met:
11  *
12  *   Redistributions of source code must retain the above
13  *   copyright notice, this list of conditions and the
14  *   following disclaimer.
15  *
16  *   Redistributions in binary form must reproduce the above
17  *   copyright notice, this list of conditions and the following
18  *   disclaimer in the documentation and/or other materials
19  *   provided with the distribution.
20  *
21  *   Neither the name of the copyright holder nor the names
22  *   of any other contributors may be used to endorse or
23  *   promote products derived from this software without
24  *   specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
27  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
28  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
39  * OF SUCH DAMAGE.
40  */
41 
42 /* Conveniance-macros to allow code like this;
43 
44    int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) );
45 
46    int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) );
47 
48    The point of course being to make sure that while in non-blocking mode
49    these always return no matter what the return code is, but in blocking mode
50    it blocks if EAGAIN is the reason for the return from the underlying
51    function.
52 
53 */
54 #define BLOCK_ADJUST(rc, sess, x) \
55     do { \
56        time_t entry_time = time(NULL); \
57        do { \
58           rc = x; \
59           /* the order of the check below is important to properly deal with \
60              the case when the 'sess' is freed */ \
61           if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
62               break; \
63           rc = _libssh2_wait_socket(sess, entry_time);  \
64        } while(!rc);   \
65     } while(0)
66 
67 /*
68  * For functions that returns a pointer, we need to check if the API is
69  * non-blocking and return immediately. If the pointer is non-NULL we return
70  * immediately. If the API is blocking and we get a NULL we check the errno
71  * and *only* if that is EAGAIN we loop and wait for socket action.
72  */
73 #define BLOCK_ADJUST_ERRNO(ptr, sess, x) \
74     do { \
75        time_t entry_time = time(NULL); \
76        int rc; \
77        do { \
78            ptr = x; \
79            if(!sess->api_block_mode || \
80               (ptr != NULL) || \
81               (libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \
82                break; \
83            rc = _libssh2_wait_socket(sess, entry_time); \
84         } while(!rc); \
85     } while(0)
86 
87 
88 int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time);
89 
90 /* this is the lib-internal set blocking function */
91 int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
92 
93 #endif /* LIBSSH2_SESSION_H */
94