I cannot epollctl() a pipe - I get Bad Address - epoll

I am trying to write a function that will make me break a epoll_wait().
I have
void SocketSystem::epollBreakWait(int epoll)
{
if (epoll == ERROR_CODE)
return;
int selfpipe[PIPE_PAIR];
if (pipe(selfpipe) < 0)
std::cout << "Error on self pipe." << std::endl;
if (::epoll_ctl(epoll, EPOLL_CTL_ADD, selfpipe[0], NULL) == ERROR_CODE)
std::cout << "Error breaking epoll." << std::endl;
int temp = 0;
::write(selfpipe[1], &temp, sizeof(temp));
}
But when I run it I get error (-1) and errno = Bad address.
Any thoughts?

How do you call epoll_wait itself? And I suppose you have to provide non null struct epoll_event to epoll_ctl

Spell it?
I have tried to put in a non null epoll_event to epoll_ctl as you suggested, and that seemed to fix the problem.

Related

Why the interpreter complains that library named "math" does not exist?

Why the interpreter complains that library named "math" does not exist?
As far as I know, this library is loaded when invoking luaL_newstate on Lua-5.3.5.
#include "lua.hpp"
#include <iostream>
#include <assert.h>
#include <fstream>
int main()
{
struct lua_State *L = luaL_newstate();
int ret;
std::string fileName("co.lua");
if(fileName.empty())
{
std::cout << "the filename is empty" << std::endl;
return -1;
}
std::ifstream fileScript(fileName, fileScript.in|std::ios::ate);
if(!fileScript.is_open())
{
std::cout << "open file failed" << std::endl;
return -2;
}
size_t size = fileScript.tellg();
if(size <= 0)
{
std::cout << "file has no valid content" << std::endl;
return -3;
}
std::string textCont(size, '\0');
fileScript.seekg(0);
fileScript.read(&textCont[0], size);
if((ret=luaL_loadbuffer(L, textCont.data(), textCont.length(), "co.lua")) == LUA_OK)
{
if((ret=lua_pcall(L, 0, LUA_MULTRET, 0)) != LUA_OK)
{
std::cout << "error in invoking lua_pcall():" << ret << std::endl;
if(lua_isstring(L, -1))
{
const char *errMsg = lua_tostring(L, -1);
lua_pop(L, 1);
std::cout << "script run encounter err:" << errMsg << std::endl;
}
}
}
}
Here is the code snippet(it's very simple) for the file named "co.lua":
a = 1;
b=2;
a=a+1;
math.sin(a)
Here is the error message in the console:
error in invoking lua_pcall():2
script run encounter err:[string "co.lua"]:29: attempt to index a nil value (global 'math')
The documentation states that you need to call luaL_openlibs or luaL_requiref which does not seem to be the case with your posted program.
To have access to these libraries, the C host program should call the luaL_openlibs function, which opens all standard libraries.
Alternatively (emphasis mine):
Alternatively, the host program can open them individually by using luaL_requiref to call:
luaopen_base (for the basic library)
luaopen_package (for the package library)
luaopen_coroutine (for the coroutine library)
luaopen_string (for the string library)
luaopen_utf8 (for the UTF8 library)
luaopen_table (for the table library)
luaopen_math (for the mathematical library)
luaopen_io (for the I/O library)
luaopen_os (for the operating system library)
luaopen_debug (for the debug library).
These functions are declared in lualib.h.
So change your program's first few lines to something like below.
You also need to compare the return value from luaL_newstate with NULL and handle that error condition.
int main()
{
struct lua_State *L = luaL_newstate();
if( L == NULL ) {
puts( "Lua failed to initialize." );
exit(1);
}
luaL_openlibs( L );
// etc

Libqmi - glib callback function not getting called

I am new to libqmi and wanted to start by just opening a new device. But the callback function is never getting called and therefore no device object returned.
I running the code on Ubuntu 64 Bit.
On this website: https://developer.gnome.org/gio/stable/GAsyncResult.html
I found how this should be handled and programmed it that way, but it still doesn't work.
#include <iostream>
#include <libqmi-glib/libqmi-glib.h>
#include <gio/gio.h>
using namespace std;
void device_create_start(const char* device_file);
void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data);
int something = 0;
int main()
{
cout << "Start\n";
device_create_start("/dev/cdc-wdm0");
cout << "DEBUG: Something: " << something << "\n";
cout << "Stop\n";
return 0;
}
void device_create_start(const char* device_file)
{
GFile* file = g_file_new_for_path(device_file);
if(file)
{
GCancellable* cancellable = g_cancellable_new();
GAsyncReadyCallback callback = device_create_stop;
gpointer user_data = NULL;
cout << "INFO: qmi_device_new starting!\n";
qmi_device_new(file, cancellable, callback, user_data);
cout << "INFO: qmi_device_new started!\n";
cout << "INFO: Waiting!\n";
usleep(10000);
cout << "INFO: Is cancelled?: " << g_cancellable_is_cancelled(cancellable) << "\n";
cout << "INFO: canceling!\n";
g_cancellable_cancel(cancellable);
cout << "INFO: Waiting again!\n";
usleep(100000);
cout << "INFO: Is cancelled?: " << g_cancellable_is_cancelled(cancellable) << "\n";
something = 1;
}
else
{
cout << "ERROR: Could not create device file!\n";
}
}
void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data)
{
cout << "INFO: device_create_stop\n";
something = 2;
cout << "INFO: qmi_device_new_finish starting\n";
GError *error;
QmiDevice* device = qmi_device_new_finish(res, &error);
cout << "INFO: qmi_device_new_finish started\n";
if(device == NULL)
{
cout << "ERROR: Could not create device!\n";
}
else
{
cout << "INFO: Device created!\n";
//device_open(device);
}
}
When I run this code the output is:
Start
INFO: qmi_device_new starting!
INFO: qmi_device_new started!
INFO: Waiting!
INFO: Is cancelled?: 0
INFO: canceling!
INFO: Waiting again!
INFO: Is cancelled?: 1
DEBUG: Something: 1
Stop
The code in the callback function is never called.
Update 1
I simplified the code and changed some things that I oversaw on the gnome reference site, like a static callback function. But this doesn't work either
#include <iostream>
#include <libqmi-glib/libqmi-glib.h>
#include <gio/gio.h>
#include <glib/gprintf.h>
using namespace std;
void device_create_start(const char* device_file);
static void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data);
int something = 0;
int main()
{
g_printf ("Start\n");
device_create_start("/dev/cdc-wdm0");
cout << "DEBUG: Something: " << something << "\n";
while(true)
{
;
}
cout << "Stop\n";
return 0;
}
void device_create_start(const char* device_file)
{
GFile* file = g_file_new_for_path(device_file);
if(file)
{
cout << "INFO: qmi_device_new starting!\n";
qmi_device_new(file, NULL, device_create_stop, NULL);
cout << "INFO: qmi_device_new started!\n";
something = 1;
}
else
{
cout << "ERROR: Could not create device!\n";
}
}
static void device_create_stop(GObject* obj, GAsyncResult* res, gpointer data)
{
g_printf ("Hurray!\n");
something = 2;
}
The new output:
Start
INFO: qmi_device_new starting!
INFO: qmi_device_new started!
DEBUG: Something: 1
Does anyone has a clue why this is not working?
As Philip said (hey Philip!), you're missing the main loop. The qmi_device_new() function is an method that finishes asynchronously, and once finished, the result of the operation is provided in the callback function you provide. In order for the asynchronous function to even do something, you need to have a GMainLoop running for as long as your program logic runs.

OpenCV FileStorage empty after loading

Im trying to load a string into filestorage. I will not have the file to pass filename as a parameter to load it. Instead I recive an xml document as a string. In the doc http://docs.opencv.org/modules/core/doc/xml_yaml_persistence.html#filestorage it is mentioned that source attribute of fs.open can be "text string to read the data from". I run some simple tests with OpenCv CascadeClassifier as a string but I get an empty FileStorage. What am I doing wrong?
CascadeClassifier face_cascade;
std::ifstream t("haarcascade_frontalface_alt.xml");
std::string ClasifierInString((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
cout << ClasifierInString << endl; //I CAN PRINT THE FILE AND SEE IT
cv::FileStorage fs;
if (!fs.open(ClasifierInString, cv::FileStorage::READ | cv::FileStorage::MEMORY | cv::FileStorage::FORMAT_XML))
{
cout << "Couldn't load file into memory" << endl;
return -2;
}
FileNodeIterator it = fs.getFirstTopLevelNode().begin(), it_end = fs.getFirstTopLevelNode().end();
for (; it != it_end; ++it)
{
cout << (string)*it << "\n"; //EMPTY LINE????
}
if (!face_cascade.read(fs.getFirstTopLevelNode()))
{
cout << "Couldn't read file from memory" << endl;
return -1;
}
EDIT:
#sop can't comment yet. Maybe your using older version of OpenCV. I have the file and I am able to load it with:
face_cascade.load("haarcascade_frontalface_alt.xml");
and it works. The problem is I'm unable to read it as a string with face_cascade.read(string)
#berak comment is the correct answer. I used lbpcascade_frontalface.xml as this is new cascade (and is faster! :) Thx for help.
I think your problem is the file name: "haarcascade_frontalface_alt.xml". There is no such a file in the OpenCV flder... Try "haarcascade_frontalface_alt_tree.xml".
Here is my code that works:
cv::CascadeClassifier face_cascade;
std::ifstream t("haarcascade_frontalface_alt_tree.xml");
std::string ClasifierInString((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
std::cout << ClasifierInString << std::endl; //I CAN PRINT THE FILE AND SEE IT
cv::FileStorage fs;
if (!fs.open(ClasifierInString, /*cv::FileStorage::READ | */cv::FileStorage::MEMORY | cv::FileStorage::FORMAT_XML))
{
std::cout << "Couldn't load file into memory" << std::endl;
return -2;
}
cv::FileNodeIterator it = fs.getFirstTopLevelNode().begin(), it_end = fs.getFirstTopLevelNode().end();
for (; it != it_end; ++it)
{
std::cout << (std::string)*it << "\n"; //EMPTY LINE????
}
if (!face_cascade.read(fs.getFirstTopLevelNode()))
{
std::cout << "Couldn't read file from memory" << std::endl;
return -1;
}

"require" not work in embeded lua

in this code i load and run test.lua file
int main (){
L = luaL_newstate();
luaL_openlibs(L);
luaL_dofile(L, "test.lua");
lua_close(L);
return 0;
}
my test.lua file contents
print ("s1");
r=require 'simple';
print ("s2");
the simple module is installed before
when run ./lua_c ; output is only: s1
but when run lua test.lua; output is
s1
s2
and r in't nil
simple is failing to load or parse or execute. To find problem, use luaL_loadfile instead of luaL_dofile and check the return value. If non zero, there was a load error, which you can pop off the Lua stack and print. If no error, do the lua_pcall(L, 0, LUA_MULTRET, 0)) to run the chuck created by loadfile, and again check return code for error, pop off stack and print. It would be somehting like this:
int main ()
{
L = luaL_newstate();
luaL_openlibs(L);
if (luaL_loadfile(L, "test.lua"))
{
cout << "Error: " << lua_tostring(L, -1) << endl;
}
else if (lua_pcall(L, 0, LUA_MULTRET, 0))
{
cout << "Error: " << lua_tostring(L, -1) << endl;
}
else
{
// call successful
}
lua_close(L);
return 0;
}
Update: now that you know from the error message that simple.so has undefined symbol: lua_gettop, you know that there is a link error. Perhaps simple.so isn't linked to lua51.so, but since it works from lua.exe, which is linked to lua lib, one would it would work from your app, which is surely linked to it too. Another possibility is that lua.exe is statically linked but simple.so is not linked. Verify that simple.so is linked to lua51.so and that the lib it links to can be found such as via LD_LIBRARY_PATH. Verify lua.exe is linked to same .so.

Boost Asio SSL Certification on iOS

I am trying to use Boost Asio on iOS, and have figured out everything, but how to check the certificate of the server I am connecting to.
How do you check the connecting server's certificate in iOS with Boost Asio?
In another answer of mine you can see a simple SSL client.
In this code you'll quickly note verify_certificate which you can use to (additionally) verify the server certificate.
Sidenote
Note that I don't know which libraries are underlying the Asio SSL implementation iOS, but keep in mind verifying (or even pinning) theserver certificate could be rather useless. It would only verify the authenticity of the certificate presented. In the light of yesterday's security debacle I don't think this helps much, because unless properly patched the server could have presented a valid certificate, but still use unrelated encryption keys - this still allows a MiTM scenario
Just noting this in case your question is somehow related to this situration
From A: HTTPS POST request with boost asio
#define DEMO_USING_SSL
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <iostream>
#include <iomanip>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
class client
{
public:
client(boost::asio::io_service& io_service,
boost::asio::ssl::context& context,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
: socket_(io_service
#ifdef DEMO_USING_SSL
, context)
{
socket_.set_verify_mode(boost::asio::ssl::verify_peer);
socket_.set_verify_callback(
boost::bind(&client::verify_certificate, this, _1, _2));
#else
)
{
(void) context;
#endif
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&client::handle_connect, this,
boost::asio::placeholders::error));
}
bool verify_certificate(bool preverified,
boost::asio::ssl::verify_context& ctx)
{
// The verify callback can be used to check whether the certificate that is
// being presented is valid for the peer. For example, RFC 2818 describes
// the steps involved in doing this for HTTPS. Consult the OpenSSL
// documentation for more details. Note that the callback is called once
// for each certificate in the certificate chain, starting from the root
// certificate authority.
// In this example we will simply print the certificate's subject name.
char subject_name[256];
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
std::cout << "Verifying " << subject_name << "\n";
return preverified;
}
void handle_connect(const boost::system::error_code& error)
{
#ifdef DEMO_USING_SSL
if (!error)
{
socket_.async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&client::handle_handshake, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Connect failed: " << error.message() << "\n";
}
#else
handle_handshake(error);
#endif
}
void handle_handshake(const boost::system::error_code& error)
{
if (!error)
{
std::cout << "Enter message: ";
static char const raw[] = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: close\r\n\r\n";
static_assert(sizeof(raw)<=sizeof(request_), "too large");
size_t request_length = strlen(raw);
std::copy(raw, raw+request_length, request_);
{
// used this for debugging:
std::ostream hexos(std::cout.rdbuf());
for(auto it = raw; it != raw+request_length; ++it)
hexos << std::hex << std::setw(2) << std::setfill('0') << std::showbase << ((short unsigned) *it) << " ";
std::cout << "\n";
}
boost::asio::async_write(socket_,
boost::asio::buffer(request_, request_length),
boost::bind(&client::handle_write, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Handshake failed: " << error.message() << "\n";
}
}
void handle_write(const boost::system::error_code& error,
size_t /*bytes_transferred*/)
{
if (!error)
{
std::cout << "starting read loop\n";
boost::asio::async_read_until(socket_,
//boost::asio::buffer(reply_, sizeof(reply_)),
reply_, '\n',
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Write failed: " << error.message() << "\n";
}
}
void handle_read(const boost::system::error_code& error, size_t /*bytes_transferred*/)
{
if (!error)
{
std::cout << "Reply: " << &reply_ << "\n";
}
else
{
std::cout << "Read failed: " << error.message() << "\n";
}
}
private:
#ifdef DEMO_USING_SSL
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
#else
boost::asio::ip::tcp::socket socket_;
#endif
char request_[1024];
boost::asio::streambuf reply_;
};
int main(int argc, char* argv[])
{
try
{
if (argc != 3)
{
std::cerr << "Usage: client <host> <port>\n";
return 1;
}
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(argv[1], argv[2]);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.set_default_verify_paths();
client c(io_service, ctx, iterator);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}

Resources