Display html page using mongoose server - mongoose-web-server

I am trying to display an html page in mongoose server
I tried using the below code which is not working can any one tell me what is the issue in that code.
#include <stdio.h>
#include <string.h>
#include "mongoose/mongoose.h"
static int begin_request_handler(struct mg_connection *conn) {
const struct mg_request_info *request_info = mg_get_request_info(conn);
static const char *login_url = "/index.html";
mg_printf(conn, "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Location: %s\r\n\r\n", login_url);
return 1;
}
int main(void) {
struct mg_context *ctx;
struct mg_callbacks callbacks;
const char *options[] = { "listening_ports", "8080", NULL };
memset(&callbacks, 0, sizeof(callbacks));
callbacks.begin_request = begin_request_handler;
ctx = mg_start(&callbacks, NULL, options);
getchar();
mg_stop(ctx);
return 0;
}

What are you trying to accomplish? In the options[] add a "document_root" (you always need a document_root in your options for mongoose), place your index.html in that directory, and remove the callbacks from mg_start. And mongoose will serve your index.html automatically.

Related

ICU4C austrdup function

I'm trying to run the code demo for ICU4C bellow, and getting
warning: implicit declaration of function 'austrdup'
which subsequently generate an error. I understand that this is due to the missing imported library that contains 'austrdup' function, and have been looking at the source code to guess which one it is, but no luck. Does anyone have any idea which one should be imported?
#include <unicode/umsg.h>
#include <unicode/ustring.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
UChar* str;
UErrorCode status = U_ZERO_ERROR;
UChar *result = NULL;
UChar pattern[100];
int32_t resultlength, resultLengthOut, i;
double testArgs[] = { 100.0, 1.0, 0.0};
str=(UChar*)malloc(sizeof(UChar) * 10);
u_uastrcpy(str, "MyDisk");
u_uastrcpy(pattern, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number,integer} files}");
for(i=0; i<3; i++){
resultlength=0;
resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, testArgs[i], str);
if(status==U_BUFFER_OVERFLOW_ERROR){ //check if output truncated
status=U_ZERO_ERROR;
resultlength=resultLengthOut+1;
result=(UChar*)malloc(sizeof(UChar) * resultlength);
u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, testArgs[i], str);
}
printf("%s\n", austrdup(result) ); //austrdup( a function used to convert UChar* to char*)
free(result);
}
return 0;
}
austrdup is not an official ICU method. It's only used by tests in ICU and defined in icu4c/source/test/cintltst/cintltst.h and implemented in icu4c/source/test/cintltst/cintltst.c. It is bascially just a wrapper around u_austrcpy.

ASIO Debug Error in MSVC Debug Build- No error in Release Build

A simple tcp client using ASIO causes abort() to be called for Debug builds. The same application in Release build works without throwing an error. The compiler is Visual Studio 2017.
Attaching a debugger to the application does not provide any additional information.
A demonstration example that takes the port as a command line argument that connects to server and disconnects immediately is shown below.
Any way I can avoid this error in the debug build?
#include <memory>
#include <string>
#include <iostream>
#include "asio.hpp"
using asio::ip::tcp;
class Client {
std::unique_ptr<asio::io_service> io_service_ = nullptr;
std::unique_ptr<tcp::socket> sock_ = nullptr;
public:
Client() {
io_service_ = std::make_unique<asio::io_service>();
sock_ = std::make_unique<tcp::socket>(*io_service_);
}
void connect(std::string hostname, unsigned int port) {
auto resolver = tcp::resolver(*io_service_);
auto query = tcp::resolver::query(hostname, std::to_string(port));
auto endpoint_iter = resolver.resolve(query);
asio::connect(*sock_, endpoint_iter);
}
};
int main(int argc, char* argv[]) {
try {
auto port = std::stoi(argv[1]);
Client client;
client.connect("localhost", port);
} catch (std::exception& e) {
std::cout << "\n" << e.what();
}
}
The common source of these are debug iterators. They're your friend, because they warn you about Undefined Behaviour in your program.
In this program, I see no such issues:
#include <iostream>
#include <memory>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
class Client {
std::unique_ptr<boost::asio::io_service> io_service_ = nullptr;
std::unique_ptr<tcp::socket> sock_ = nullptr;
public:
Client() {
io_service_ = std::make_unique<boost::asio::io_service>();
sock_ = std::make_unique<tcp::socket>(*io_service_);
}
void connect(std::string hostname, unsigned int port) {
auto resolver = tcp::resolver(*io_service_);
auto query = tcp::resolver::query(hostname, std::to_string(port));
auto endpoint_iter = resolver.resolve(query);
boost::asio::connect(*sock_, endpoint_iter);
}
};
int main() {
try {
Client client;
client.connect("localhost", 6767);
} catch (std::exception &e) {
std::cout << "\n" << e.what();
}
}
The chief difference is that I'm not using argv[1]. Since you didn't check argc, did you in fact pass arguments for the Debug configuration?

Piping in shell

i have created my own shell in linux. it works fine with commmands. Now I want to add pipes in it. i want to implement multiple piping in it. Can some one guide me how to do do? I havent used Linux. Iam new to it.
I have seen many source codes and sites but i am still not clear about the idea of executing commands having multiple pipes!
This is code i have implemented so far!
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <cstring>
#include <sys/types.h>
using namespace std;
int main ()
{
while (true){
char * input;
string insert;
char * token;
char * parsed[9];
int count=0;
char * cmd1[6];
char * cmd2[6];
cout<<"My Shell $";
getline(cin,insert); // take input from user
input= new char [insert.size()+1];
strcpy(input, insert.c_str());
for (int i=0; i<9; i++)
parsed[i]=NULL;
token=strtok(input, " ");
while (token!=NULL) // parse the input
{
parsed[count] = new char[strlen(token) + 1];
strcpy(parsed[count++],token);
token=strtok(NULL, " ");
}
delete input;
delete token;
int j= count-1;
int pipe_position[4]={0};
int counter=0;
for (int i=0; i<j; i++) // finding position of pipe
{
if ((strcmp(parsed[i],"|"))==0)
pipe_position[counter++]=i;
}
bool pipe_exists=false;
if (pipe_position[0]!=0)
pipe_exists=true;
if(pipe_exists==false) // if there isnt any pipe in the command
{
pid_t mypid=fork();
if (mypid==0)
{
execlp (parsed[0],parsed[0],parsed[1],parsed[2],parsed[3],parsed[4], parsed[5],parsed[6],parsed[7],parsed[8],(char*) NULL);
}
else if (mypid>0)
{
wait(NULL);
for(int i=0; i<9; i++)
delete[]parsed[i];
}
}
} //end of while
}

Create a rapidjson::Value from a JSON string

I want to create a rapidjson::Value from a JSON string, e.g., [1,2,3]. Note: this is not a complete JSON object, it's just a JSON array. In Java I can use objectMapper.readTree("[1,2,3]")to create a JsonNode from a String.
My complete C++ code is as the following:
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <iostream>
// just for debug
static void print_json_value(const rapidjson::Value &value) {
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
value.Accept(writer);
std::cout << buffer.GetString() << std::endl;
}
//TODO: this function probably has a problem
static rapidjson::Value str_to_json(const char* json) {
rapidjson::Document document;
document.Parse(json);
return std::move(document.Move());
}
int main(int argc, char* argv[]) {
const char* json_text = "[1,2,3]";
// copy the code of str_to_json() here
rapidjson::Document document;
document.Parse(json_text);
print_json_value(document); // works
const rapidjson::Value json_value = str_to_json(json_text);
assert(json_value.IsArray());
print_json_value(json_value); // Assertion failed here
return 0;
}
Could anyone find out the problem in my function str_to_json() ?
PS: The code above works in GCC 5.1.0 but not in Visual Studio Community 2015.
UPDATE:
According to the suggestion of #Milo Yip, the correct code is as the following:
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <iostream>
static void print_json_value(const rapidjson::Value &value) {
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
value.Accept(writer);
std::cout << buffer.GetString() << std::endl;
}
static rapidjson::Document str_to_json(const char* json) {
rapidjson::Document document;
document.Parse(json);
return std::move(document);
}
int main(int argc, char* argv[]) {
const char* json_text = "[1,2,3]";
// copy the code of str_to_json() here
rapidjson::Document document;
document.Parse(json_text);
print_json_value(document); // works
const rapidjson::Document json_value = str_to_json(json_text);
assert(json_value.IsArray());
print_json_value(json_value); // Now works
return 0;
}
Simple answer: the return type should be rapidjson::Document instead of rapidjson::Value.
Longer version: A Document contains an allocator to store all the values during parsing. When returning the Value (actually the root of the tree), the local Document object will be destructed and the buffers in the allocator will be released. It is like std::string s = ...; return s.c_str(); inside a function.

Using the Linux sysfs_notify call

I am trying to communicate asynchronously between a kernel driver and a user-space program (I know there are lots of questions here that ask for similar information, but I could find none that deal with sysfs_notify).
I am leaving Vilhelm's edit here, but adding the source to both a simple driver utilizing sysfs and a user-space program to poll it. The driver works fine (I got most of it from the net; it is missing the credits, but I couldn't find them when I went back to add them).
Unfortunately, the polling program does not work. It always returns success immediately. Interestingly, if I don't perform the two reads prior to the poll, the revents members are set to POLLERR | POLLIN instead of just POLLIN as seen in the program output.
Program output:
root#ubuntu:/home/wmulcahy/demo# ./readhello
triggered
Attribute file value: 74 (t) [0]
revents[0]: 00000001
revents[1]: 00000001
Here is the driver: hello.c (you can see where I started out...)
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
struct my_attr {
struct attribute attr;
int value;
};
static struct my_attr notify = {
.attr.name="notify",
.attr.mode = 0644,
.value = 0,
};
static struct my_attr trigger = {
.attr.name="trigger",
.attr.mode = 0644,
.value = 0,
};
static struct attribute * myattr[] = {
&notify.attr,
&trigger.attr,
NULL
};
static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct my_attr *a = container_of(attr, struct my_attr, attr);
printk( "hello: show called (%s)\n", a->attr.name );
return scnprintf(buf, PAGE_SIZE, "%s: %d\n", a->attr.name, a->value);
}
static struct kobject *mykobj;
static ssize_t store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len)
{
struct my_attr *a = container_of(attr, struct my_attr, attr);
sscanf(buf, "%d", &a->value);
notify.value = a->value;
printk("sysfs_notify store %s = %d\n", a->attr.name, a->value);
sysfs_notify(mykobj, NULL, "notify");
return sizeof(int);
}
static struct sysfs_ops myops = {
.show = show,
.store = store,
};
static struct kobj_type mytype = {
.sysfs_ops = &myops,
.default_attrs = myattr,
};
static struct kobject *mykobj;
static int __init hello_module_init(void)
{
int err = -1;
printk("Hello: init\n");
mykobj = kzalloc(sizeof(*mykobj), GFP_KERNEL);
if (mykobj) {
kobject_init(mykobj, &mytype);
if (kobject_add(mykobj, NULL, "%s", "hello")) {
err = -1;
printk("Hello: kobject_add() failed\n");
kobject_put(mykobj);
mykobj = NULL;
}
err = 0;
}
return err;
}
static void __exit hello_module_exit(void)
{
if (mykobj) {
kobject_put(mykobj);
kfree(mykobj);
}
printk("Hello: exit\n");
}
module_init(hello_module_init);
module_exit(hello_module_exit);
MODULE_LICENSE("GPL");
And here is the poll program: readhello.c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <poll.h>
#define TEST_SYSFS_TRIGGER "/sys/hello/trigger"
#define TEST_SYSFS_NOTIFY "/sys/hello/notify"
int main(int argc, char **argv)
{
int cnt, notifyFd, triggerFd, rv;
char attrData[100];
struct pollfd ufds[2];
// Open a connection to the attribute file.
if ((notifyFd = open(TEST_SYSFS_NOTIFY, O_RDWR)) < 0)
{
perror("Unable to open notify");
exit(1);
}
// Open a connection to the attribute file.
if ((triggerFd = open(TEST_SYSFS_TRIGGER, O_RDWR)) < 0)
{
perror("Unable to open trigger");
exit(1);
}
ufds[0].fd = notifyFd;
ufds[0].events = POLLIN;
ufds[1].fd = triggerFd;
ufds[1].events = POLLIN;
// Someone suggested dummy reads before the poll() call
cnt = read( notifyFd, attrData, 100 );
cnt = read( triggerFd, attrData, 100 );
ufds[0].revents = 0;
ufds[1].revents = 0;
if (( rv = poll( ufds, 2, 10000)) < 0 )
{
perror("poll error");
}
else if (rv == 0)
{
printf("Timeout occurred!\n");
}
else if (ufds[0].revents & POLLIN)
{
printf("triggered\n");
cnt = read( notifyFd, attrData, 1 );
printf( "Attribute file value: %02X (%c) [%d]\n", attrData[0], attrData[0], cnt );
}
printf( "revents[0]: %08X\n", ufds[0].revents );
printf( "revents[1]: %08X\n", ufds[1].revents );
close( triggerFd );
close( notifyFd );
}
Some upcoming sysfs enhancements.
Internally, the patch adds a wait queue head to every kobject on the
system; that queue is inserted into a poll table in response to a
poll() call. The sysfs code has no way of knowing, however, when the
value of any given sysfs attribute has changed, so the subsystem
implementing a pollable attribute must make explicit calls to:
void sysfs_notify(struct kobject *kobj, char *dir, char *attr);
Thanks,
Lee
The blocking poll is from the user side. User code can simply tell the kernel which attributes it's interested in, then block in a poll() until one of them has changed.
The sysfs_notify() is a kernel-side call that releases the user-space poll(). After you adjust your kernel attribute value, just call sysfs_notify() to allow any user-space applications to respond to their outstanding poll().
Think of the poll() as "subscribing" to notices of a change in an attribute of interest, and sysfs_notify() as "publishing" the change to any subscribers.

Resources