Skip to content

Commit

Permalink
Updated README, CHANGELOG, and CMake version for v0.8.1 release. Adde…
Browse files Browse the repository at this point in the history
…d forgotten 'result' source files.
  • Loading branch information
fpagliughi committed Jan 30, 2023
1 parent 51e19ed commit af4104f
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 7 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Change Log for _sockpp_

## [Version 0.8.1](https://github.com/fpagliughi/sockpp/compare/v0.8.0..v0.8.1)

Released: 2023-01-30

- Cherry picked most of the non-TLS commits in PR [#17](https://github.com/fpagliughi/sockpp/pull/17)
- Connector timeouts
- Stateless reads & writes for streaming sockets w/ functions returning `ioresult`
- Some small bug fixes
- No shutdown on invalid sockets
- [#38](https://github.com/fpagliughi/sockpp/issues/38) Made system libs public for static builds to fix Windows
- [#73](https://github.com/fpagliughi/sockpp/issue/73) Clone a datagram (UDP) socket
- [#74](https://github.com/fpagliughi/sockpp/issue/74) Added `<sys/time.h>` to properly get `timeval` in *nix builds.
- [#56](https://github.com/fpagliughi/sockpp/issue/56) handling unix paths with maximum length (no NUL term)
- Fixed outstanding build warnings on Windows when using MSVC

## [Version 0.8.0](https://github.com/fpagliughi/sockpp/compare/v0.7.1..v0.8.0)

Released: 2023-01-17
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ cmake_minimum_required(VERSION 3.12)

# --- Project setup ---

project(sockpp VERSION "0.8.0")
project(sockpp VERSION "0.8.1")

# --- Build Options ---

Expand Down
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ To keep up with the latest announcements for this project, follow me at:

If you're using this library, tweet at me or send me a message, and let me know how you're using it. I'm always curious to see where it winds up!

## New in v0.8.1

This release attempts to fix some of the outstanding build issues on Windows with MSVC and resolv some old issues and PR commits.

- Cherry picked most of the non-TLS commits in PR [#17](https://github.com/fpagliughi/sockpp/pull/17)
- Connector timeouts
- Stateless reads & writes for streaming sockets w/ functions returning `ioresult`
- Some small bug fixes
- No shutdown on invalid sockets
- [#38](https://github.com/fpagliughi/sockpp/issues/38) Made system libs public for static builds to fix Windows
- [#73](https://github.com/fpagliughi/sockpp/issue/73) Clone a datagram (UDP) socket
- [#74](https://github.com/fpagliughi/sockpp/issue/74) Added `<sys/time.h>` to properly get `timeval` in *nix builds.
- [#56](https://github.com/fpagliughi/sockpp/issue/56) handling unix paths with maximum length (no NUL term)
- Fixed outstanding build warnings on Windows when using MSVC


## New in v0.8.0

This was primarily a release of code that had been sitting in the develop branch for nearly a year. That code mostly improved CMake functionality for downstream projects.
Expand All @@ -46,8 +62,6 @@ For more information, refer to: [CONTRIBUTING.md](https://github.com/fpagliughi/

## TODO

- **Unit Tests** - The framework for unit and regression tests is in place (using _Catch2_), along with the GitHub Travis CI integration. But the library could use a lot more tests.
- **Consolidate Header Files** - The last round of refactoring left a large number of header files with a single line of code in each. This may be OK, in that it separates all the protocols and families, but seems a waste of space.
- **Secure Sockets** - It would be extremely handy to have support for SSL/TLS built right into the library as an optional feature.
- **SCTP** - The _SCTP_ protocol never caught on, but it seems intriguing, and might be nice to have in the library for experimentation, if not for some internal applications.

Expand Down Expand Up @@ -183,7 +197,7 @@ The same style of connectors and acceptors can be used for TCP connections over
tcp6_acceptor
tcp6_socket
udp6_socket

Examples are in the [examples/tcp](https://github.com/fpagliughi/sockpp/tree/master/examples/tcp) directory.

### Unix Domain Sockets
Expand Down Expand Up @@ -236,7 +250,7 @@ sock.recv(&frame);

## Implementation Details

The socket class hierarchy is built upon a base `socket` class. Most simple applications will probably not use `socket` directly, but rather use top-level classes defined for a specific address family like `tcp_connector` and `tcp_acceptor`.
The socket class hierarchy is built upon a base `socket` class. Most simple applications will probably not use `socket` directly, but rather use derived classes defined for a specific address family like `tcp_connector` and `tcp_acceptor`.

The socket objects keep a handle to an underlying OS socket handle and a cached value for the last error that occurred for that socket. The socket handle is typically an integer file descriptor, with values >=0 for open sockets, and -1 for an unopened or invalid socket. The value used for unopened sockets is defined as a constant, `INVALID_SOCKET`, although it usually doesn't need to be tested directly, as the object itself will evaluate to _false_ if it's uninitialized or in an error state. A typical error check would be like this:

Expand Down Expand Up @@ -273,10 +287,10 @@ It is a common patern, especially in client applications, to have one thread to
The solution for this case is to use the `socket::clone()` method to make a copy of the socket. This will use the system's `dup()` function or similar create another socket with a duplicated copy of the socket handle. This has the added benefit that each copy of the socket can maintain an independent lifetime. The underlying socket will not be closed until both objects go out of scope.

sockpp::tcp_connector conn({host, port});

auto rdSock = conn.clone();
std::thread rdThr(read_thread_func, std::move(rdSock));

The `socket::shutdown()` method can be used to communicate the intent to close the socket from one of these objects to the other without needing another thread signaling mechanism.
The `socket::shutdown()` method can be used to communicate the intent to close the socket from one of these objects to the other without needing another thread signaling mechanism.

See the [tcpechomt.cpp](https://github.com/fpagliughi/sockpp/blob/master/examples/tcp/tcpechomt.cpp) example.
126 changes: 126 additions & 0 deletions include/sockpp/result.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/// @file result.h
///
/// Type(s) for return values that can indicate a success or failure.
///
/// @date January 2023

// --------------------------------------------------------------------------
// This file is part of the "sockpp" C++ socket library.
//
// Copyright (c) 2023 Frank Pagliughi
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --------------------------------------------------------------------------

#ifndef __sockpp_result_h
#define __sockpp_result_h

#include "sockpp/platform.h"

namespace sockpp {

/////////////////////////////////////////////////////////////////////////////

/**
* Result of a thread-safe I/O operation.
*
* Most I/O operations in the OS will return >=0 on sccess and -1 on error.
* In the case of an error, the calling thread must read an `errno` variable
* immediately, before any other system calls, to get the cause of an error
* as an integer value defined by the constants ENOENT, EINTR, EBUSY, etc.
*
* Most sockpp calls retain this known behavior, but will cache this errno
* value to be read later by a call to @ref socket::last_error() or similar.
* But this makes the @ref socket classes themselves non-thread-safe since
* the cached errno variable can't be shared across threads.
*
* Several new "thread-safe" variants of I/O functions simply retrieve the
* errno immediately on a failed I/O call and instead of caching the value,
* return it immediately in this ioresult.
* See: @ref stream_socket::read_r, @ref stream_socket::read_n_r, @ref
* stream_socket::write_r, etc.
*/
class ioresult {
/** Byte count, or 0 on error or EOF */
size_t cnt_ = 0;
/** errno value (0 if no error or EOF) */
int err_ = 0;

/**
* OS-specific means to retrieve the last error from an operation.
* This should be called after a failed system call to get the caue of
* the error.
*/
static int get_last_error();

friend class socket;

public:
/** Creates an empty result */
ioresult() = default;
/**
* Creates a result from the return value of a low-level I/O function.
* @param n The number of bytes read or written. If <0, then an error is
* assumed and obtained from socket::get_last_error().
*
*/
explicit inline ioresult(ssize_t n) {
if (n < 0)
err_ = get_last_error();
else
cnt_ = size_t(n);
}

/** Sets the error value */
void set_error(int e) { err_ = e; }

/** Increments the count */
void incr(size_t n) { cnt_ += n; }

/** Determines if the result is OK (not an error) */
bool is_ok() const { return err_ == 0; }
/** Determines if the result is an error */
bool is_err() const { return err_ != 0; }

/** Determines if the result is OK */
explicit operator bool() const { return is_ok(); }

/** Gets the count */
size_t count() const { return cnt_; }

/** Gets the error */
int error() const { return err_; }
};

/////////////////////////////////////////////////////////////////////////////
// end namespace sockpp
}

#endif // __sockpp_result_h

59 changes: 59 additions & 0 deletions src/result.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

// acceptor.cpp
//
// --------------------------------------------------------------------------
// This file is part of the "sockpp" C++ socket library.
//
// Copyright (c) 2014-2017 Frank Pagliughi
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --------------------------------------------------------------------------

#include "sockpp/result.h"

using namespace std;

namespace sockpp {

/////////////////////////////////////////////////////////////////////////////

int ioresult::get_last_error()
{
#if defined(_WIN32)
return ::WSAGetLastError();
#else
int err = errno;
return err;
#endif
}

/////////////////////////////////////////////////////////////////////////////
// end namespace sockpp
}

0 comments on commit af4104f

Please sign in to comment.