LCOV - code coverage report
Current view: top level - eventdispatcher - fd_connection.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 27 0.0 %
Date: 2019-08-10 01:48:51 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2012-2019  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/eventdispatcher
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software; you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation; either version 2 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License
      17             : // along with this program; if not, write to the Free Software
      18             : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      19             : 
      20             : /** \file
      21             :  * \brief Implementation of the Snap Communicator class.
      22             :  *
      23             :  * This class wraps the C poll() interface in a C++ object with many types
      24             :  * of objects:
      25             :  *
      26             :  * \li Server Connections; for software that want to offer a port to
      27             :  *     which clients can connect to; the server will call accept()
      28             :  *     once a new client connection is ready; this results in a
      29             :  *     Server/Client connection object
      30             :  * \li Client Connections; for software that want to connect to
      31             :  *     a server; these expect the IP address and port to connect to
      32             :  * \li Server/Client Connections; for the server when it accepts a new
      33             :  *     connection; in this case the server gets a socket from accept()
      34             :  *     and creates one of these objects to handle the connection
      35             :  *
      36             :  * Using the poll() function is the easiest and allows us to listen
      37             :  * on pretty much any number of sockets (on my server it is limited
      38             :  * at 16,768 and frankly over 1,000 we probably will start to have
      39             :  * real slowness issues on small VPN servers.)
      40             :  */
      41             : 
      42             : 
      43             : // self
      44             : //
      45             : #include    "eventdispatcher/fd_connection.h"
      46             : 
      47             : 
      48             : // C lib
      49             : //
      50             : #include    <unistd.h>
      51             : 
      52             : 
      53             : // last include
      54             : //
      55             : #include    <snapdev/poison.h>
      56             : 
      57             : 
      58             : 
      59             : namespace ed
      60             : {
      61             : 
      62             : 
      63             : 
      64             : /** \brief Initializes the file descriptor connection.
      65             :  *
      66             :  * This function creates a connection based on an existing file descriptor.
      67             :  * This is a class used to handle existing pipes or socket (opposed to other
      68             :  * implementations which create a pipe, open a socket, etc.) It is especially
      69             :  * useful if you want to listen to stdin and stdout. Use the `fileno()`
      70             :  * function to get the file descriptor and create a `snap_fd_connection`
      71             :  * object what that descriptor.
      72             :  *
      73             :  * The mode parameter defines how you are to use the file descriptor. In
      74             :  * other words, a socket that is read/write could be added to two different
      75             :  * `snap_fd_connection` objects: one to read and one to write, instead of
      76             :  * a single read/write object.
      77             :  *
      78             :  * Note that although you can say it's only going to be used in READ or
      79             :  * in WRITE mode, in all cases, make sure that the file is readable before
      80             :  * specifying READ or RW, and make sure that the file is writable before
      81             :  * specifying WRITE or RW.
      82             :  *
      83             :  * \note
      84             :  * It is important to note that the lifetime of the file desriptor is
      85             :  * not managed by this object. You are responsible for the descriptor to
      86             :  * stay valid as long as the connection is added to the snap_communicator
      87             :  * list of connections. If you want to close the connection, please first
      88             :  * remove the connection from the snap_communicator, destroy the connection,
      89             :  * then close the file descriptor.
      90             :  *
      91             :  * \note
      92             :  * It is possible to pass -1 (or any negative number) as the file
      93             :  * descriptor. In that case it is interpreted as "not a valid
      94             :  * file descriptor."
      95             :  *
      96             :  * \warning
      97             :  * If you are to use a read() or a write() that may block, make sure to
      98             :  * first set your file descriptor in non-blocking mode. If that's not
      99             :  * possible, then make sure to read or write only one byte at a time.
     100             :  * The loop will be slower, but you will avoid blocks which would
     101             :  * prevent the rest of the software from getting their own events.
     102             :  *
     103             :  * \param[in] fd  The file descriptor to handle.
     104             :  * \param[in] mode  The mode this descriptor is to be used by the connection.
     105             :  */
     106           0 : fd_connection::fd_connection(int fd, mode_t mode)
     107             :     : f_fd(fd)
     108           0 :     , f_mode(mode)
     109             : {
     110           0 : }
     111             : 
     112             : 
     113             : /** \brief Used to close the file descriptor.
     114             :  *
     115             :  * This function closes the file descript of this connection.
     116             :  *
     117             :  * The function is not called automatically as we mention in the
     118             :  * constructor, the function cannot just close the file descriptor
     119             :  * on its own so it is up to you to call this function or not.
     120             :  * It is not mandatory.
     121             :  *
     122             :  * The function does not verify to know whether the file descriptor
     123             :  * was already closed outside of this function. Although it is safe
     124             :  * to call this function multiple times, if you close the file
     125             :  * descriptor with other means, then calling this function may
     126             :  * end up closing another file...
     127             :  */
     128           0 : void fd_connection::close()
     129             : {
     130           0 :     if(f_fd != -1)
     131             :     {
     132           0 :         ::close(f_fd);
     133           0 :         f_fd = -1;
     134             :     }
     135           0 : }
     136             : 
     137             : 
     138             : /** \brief Used to mark the file descriptor as closed.
     139             :  *
     140             :  * This function marks the file descriptor as closed. Whether it is,
     141             :  * is your own concern. This is used to avoid a double close in
     142             :  * case some other function ends up calling close() and yet you
     143             :  * somehow closed the file descriptor (i.e. fclose(f) will do that
     144             :  * on you...)
     145             :  *
     146             :  * \code
     147             :  *      ...
     148             :  *      fclose(f);
     149             :  *      // tell connection that we've close the connection fd
     150             :  *      c->mark_closed();
     151             :  *      ...
     152             :  * \endcode
     153             :  *
     154             :  * Note that if you do not have any other copy of the file descriptor
     155             :  * and you call mark_closed() instead of close(), you will leak that
     156             :  * file descriptor.
     157             :  */
     158           0 : void fd_connection::mark_closed()
     159             : {
     160           0 :     f_fd = -1;
     161           0 : }
     162             : 
     163             : 
     164             : /** \brief Check whether this connection is a reader.
     165             :  *
     166             :  * If you created this file descriptor connection as a reader, then this
     167             :  * function returns true.
     168             :  *
     169             :  * A reader has a mode of FD_MODE_READ or FD_MODE_RW.
     170             :  *
     171             :  * \return true if the connection is considered to be a reader.
     172             :  */
     173           0 : bool fd_connection::is_reader() const
     174             : {
     175           0 :     return f_mode != mode_t::FD_MODE_WRITE && get_socket() != -1;
     176             : }
     177             : 
     178             : 
     179             : /** \brief Check whether this connection is a writer.
     180             :  *
     181             :  * If you created this file descriptor connection as a writer, then this
     182             :  * function returns true.
     183             :  *
     184             :  * A writer has a mode of FD_MODE_WRITE or FD_MODE_RW.
     185             :  *
     186             :  * \return true if the connection is considered to be a writer.
     187             :  */
     188           0 : bool fd_connection::is_writer() const
     189             : {
     190           0 :     return f_mode != mode_t::FD_MODE_READ && get_socket() != -1;
     191             : }
     192             : 
     193             : 
     194             : /** \brief Return the file descriptor ("socket").
     195             :  *
     196             :  * This function returns the file descriptor specified in the constructor.
     197             :  *
     198             :  * The current naming convention comes from the fact that the library
     199             :  * was first created for sockets.
     200             :  *
     201             :  * \return The connection file descriptor.
     202             :  */
     203           0 : int fd_connection::get_socket() const
     204             : {
     205           0 :     return f_fd;
     206             : }
     207             : 
     208             : 
     209             : /** \brief Read up data from the file descriptor.
     210             :  *
     211             :  * This function attempts to read up to \p count bytes of data from
     212             :  * this file descriptor. If that works to some extend, then the
     213             :  * data read will be saved in \p buf and the function returns
     214             :  * the number of bytes read.
     215             :  *
     216             :  * If no data can be read, the function may return -1 or 0.
     217             :  *
     218             :  * The file descriptor must be a reader or the function will always fail.
     219             :  *
     220             :  * \param[in] buf  The buffer where the data read is saved.
     221             :  * \param[in] count  The maximum number of bytes to read at once.
     222             :  */
     223           0 : ssize_t fd_connection::read(void * buf, size_t count)
     224             : {
     225             :     // WARNING: We MUST call the fd_connection version of the is_writer(),
     226             :     //          because the fd_buffer_connection::is_writer() also checks
     227             :     //          the f_output buffer which has unwanted side effects
     228             :     //
     229           0 :     if(!fd_connection::is_reader())
     230             :     {
     231           0 :         errno = EBADF;
     232           0 :         return -1;
     233             :     }
     234             : 
     235           0 :     return ::read(f_fd, buf, count);
     236             : }
     237             : 
     238             : 
     239             : /** \brief Write buffer data to the file descriptor.
     240             :  *
     241             :  * This function writes \p count bytes of data from \p buf to
     242             :  * the file descriptor attached to this connection.
     243             :  *
     244             :  * If the file descriptor is closed, then an error occurs and
     245             :  * the function returns -1.
     246             :  *
     247             :  * \note
     248             :  * If you setup the file descriptor in non-blocking mode, then the
     249             :  * function will return early if it cannot cache or immediately
     250             :  * send the specified data.
     251             :  *
     252             :  * \param[in] buf  A pointer to a buffer of data to write to the file.
     253             :  * \param[in] count  The number of bytes to write to the file.
     254             :  *
     255             :  * \return The number of bytes written to the file.
     256             :  */
     257           0 : ssize_t fd_connection::write(void const * buf, size_t count)
     258             : {
     259             :     // WARNING: We MUST call the fd_connection version of the is_writer(),
     260             :     //          because the fd_buffer_connection::is_writer() also checks
     261             :     //          the f_output buffer which has unwanted side effects
     262             :     //
     263           0 :     if(!fd_connection::is_writer())
     264             :     {
     265           0 :         errno = EBADF;
     266           0 :         return -1;
     267             :     }
     268             : 
     269           0 :     return ::write(f_fd, buf, count);
     270             : }
     271             : 
     272             : 
     273             : 
     274             : } // namespace ed
     275             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.12