Function called from external .c file does nothing - c

I am trying to setup a function for a mosquitto pub command. This command is held in a separate .c file from the main .c file. Everything compiles fine but when I call the function (called within the external .c file) from within the external .c file nothing happens. Conversely if I invoke the function in it's own compiled program with no external .c file, the function acts as it should. Realizing that I am doing something wrong, I tried to do something simple by a simple printf function and calling it in the external .c file and it compiles fine but still doesn't print my data. What am I doing wrong? I have the function defined in the .h also.
void mosquittoto(void)
{
struct mosquitto *mosq = NULL;
// Initialize the Mosquitto library
mosquitto_lib_init();
// Create a new Mosquitto runtime instance with a random client ID,
// and no application-specific callback data.
mosq = mosquitto_new (NULL, true, NULL);
if (!mosq)
{
fprintf (stderr, "Can't initialize Mosquitto library\n");
exit (-1);
}
mosquitto_username_pw_set (mosq, MQTT_USERNAME, MQTT_PASSWORD);
// Establish a connection to the MQTT server. Do not use a keep-alive ping
int ret = mosquitto_connect (mosq, MQTT_HOSTNAME, MQTT_PORT, 0);
if (ret)
{
fprintf (stderr, "Can't connect to Mosquitto server\n");
exit (-1);
}
int i;
char text[20];
for (i = 0; i < 10; i++)
{
//sprintf (text, "Hello, World %d", i);
// Publish the message to the topic
ret = mosquitto_publish (mosq, NULL, MQTT_TOPIC,
strlen (epc4pub), epc4pub, 0, false);
if (ret)
{
fprintf (stderr, "Can't publish to Mosquitto server\n");
exit (-1);
}
}
// We need a short delay here, to prevent the Mosquitto library being
// torn down by the operating system before all the network operations
// are finished.
sleep (1);
// Tidy up
mosquitto_disconnect (mosq);
mosquitto_destroy (mosq);
mosquitto_lib_cleanup();
}
I have the function defined in the .h file as:
void mosquittoto(void);
Thank you all for your help!

Related

Shared object library usage in gambas

I need to use mqtt protocol in gambas to get jobs done.
I used mosquitto api and mosquitto-dev library then created something like that:
`
#include <stdio.h>
#include <mosquitto.h>
int connectt(char *mqname,bool mqbool){
printf("something happens...1");
int rc;
struct mosquitto * mosq;
mosquitto_lib_init();
mosq=mosquitto_new(mqname,mqbool,NULL);
mosquitto_connect(mosq,"localhost",1883,60);
if(rc!=0){
printf("i cant connect to broker");
mosquitto_destroy(mosq);
return -1;
}else if(rc==0){
printf("Connected to broker yeey");
return 0;
}
mosquitto_publish(mosq,NULL,"targe/test",6,"Yeey",0,false);
mosquitto_disconnect(mosq);
printf("something happening...2");
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
printf("something happening...3");
return 0;
int main(){
connectt("tester",true);
}
and i created shared object file with this way:
1gcc -c -g mosquit.c -lmosquitto
gcc -shared -o libmosquit.so mosquit.o
gcc -Llib/ -Wall -o targele mosquit.c -lmosquitto
so i moved libmosquit.so file to /lib/x86_64-linux-gnu/ directory
Untill here everything is fine, when i run targele it send "Yeeyt" payload but when i try it in gambas with these lines
`
Library "libmosquit"
Extern connectt(mqname As String, mqbool As Boolean) As Integer
Public Sub Main()
connectt("tester", True)
End
`
it says connection estabilished but do not send payload.
I tried directy importing library from mosquitto api but i couldn't figure out gambas structures and i don't need all of those functions
Your code returns if rc != 0 or rc == 0 (i.e. in all cases) meaning the call to mosquitto_publish is never reached. In your case rc is never set, you define it (int rc), but do not assign anything to it i.e. rc = mosquitto_connect(mosq, "test.mosquitto.org", 1883, 60); so effectively your code is:
int rc
if (rc != 0) {
printf("i cant connect to broker");
mosquitto_destroy(mosq);
return -1;
} else if (rc == 0) {
printf("Connected to broker yeey");
return 0;
}
// Any code below here is unreachable
When you have fixed that you may run into another issue; you might find this example useful. mosquitto_connect "makes the socket connection only, it does not complete the MQTTCONNECT/CONNACK flow, you should use mosquitto_loop_start() or mosquitto_loop_forever() for processing net traffic".

pcap_set_rfmon return 0 as success but the interface is not set to monitor mode

I'm trying to write a small program which set my network interface to monitor mode using C, the function pcap_set_rfmon returns 0 as success but the interface is still in mange mode. I'm sure my network card supports Monitor mode because i have checked using ng-airmon and iwconfig wlp3s0 mode monitor the wlp3s0 is my network interface's name.
Here's my code:
#include <pcap.h>
main()
{
char error_buffer[PCAP_ERRBUF_SIZE];
pcap_t *handle = pcap_create("wlp3s0", error_buffer);
int result = pcap_set_rfmon(handle, 1);
if (result != 0)
{
printf("failed to set pcap rfmon");
}
}
Since the code output nothing and just returns 0, i don't know what has gone wrong and where to look at, can you guys tell me what i should check or something is missing
To quote the documentation for pcap_set_rfmon():
pcap_set_rfmon() sets whether monitor mode should be set on a capture handle when the handle is activated. ...
I've emphasized part of that - "when the handle is activated". All pcap_set_rfmon() does is set a flag in the pcap_t to indicate that, when the program calls pcap_activate(), the adapter would be put in monitor mode (if pcap_activate() succeeds).
You aren't calling pcap_activate(), so nothing happens.
You will also have to keep the pcap_t open - even a program that does
#include <pcap.h>
main()
{
char error_buffer[PCAP_ERRBUF_SIZE];
pcap_t *handle;
int result;
handle = pcap_create("wlp3s0", error_buffer);
if (handle == NULL)
{
printf("failed to create a handle: %s\n",
error_buffer);
return 2;
}
result = pcap_set_rfmon(handle, 1);
if (result != 0)
{
printf("failed to set pcap rfmon: %s (%s)\n",
pcap_statustostr(result),
pcap_geterr(handle));
return 2;
}
result = pcap_activate(handle);
{
printf("failed to activate handle: %s (%s)\n",
pcap_statustostr(result),
pcap_geterr(handle));
return 2;
}
}
will just let the adapter revert to managed mode when it exits. You will need to add something such as
for (;;)
pause();
at the end of main(), so the program doesn't exit unless you interrupt or terminate it.
(Note: I added more error checking and reporting to the program. This Is A Good Thing, as it means that, if something doesn't work, the program will give a detailed error report, helping you - or whoever you ask for help - try to fix the problem, rather than just silently failing or, if pcap_create() fails, crashing.)

Where would my data be getting lost at within this mutex/pthread_cond_wait structure?

FINAL EDIT: Solution to problem was stated by the answer I have selected. The representative example code is shown in the diff here
EDIT: Full compile-able code at the bottom of the post.
I have this rudimentary multithreaded server that simply accepts a connection and is supposed to pass the file descriptor off to a thread to allow this thread to handle it directly until the client disconnects.
For some reason, even with the following code flow inside of the server, some clients "Fall through the cracks" and get stuck in limbo. (They never get handled by the server so they just hang after accepting the connection)
The following block is my server main running loop:
while(g_serv.b_running)
{
//printf("Awaiting connection.\n");
client_fd = accept(g_serv.serv_listener_fd,
(struct sockaddr*)&cli_addr,
&clilen);
if (0 > client_fd)
{
fprintf(stderr,
"Error accepting connection. [%s]\n",
strerror(errno));
continue;
}
err = sem_trywait(&(g_serv.client_count_sem));
if (0 > err)
{
fprintf(stderr,
"Max connections reached. [%s]\n",
strerror(errno));
notify_client_max_connections(client_fd);
close(client_fd);
client_fd = 0;
continue;
}
printf("A client has connected.\n");
char byte[2] = "0";
err = send(client_fd, byte, 1, 0);
// Set up client FD in global position and wake up a thread to grab it
//
pthread_mutex_lock(&(g_serv.new_connection_fd_lock));
g_serv.new_connection_fd = client_fd;
if (0 != g_serv.new_connection_fd)
{
pthread_cond_signal(&(g_serv.new_connection));
}
pthread_mutex_unlock(&(g_serv.new_connection_fd_lock));
}
This block is the thread handling function:
void* thread_handler(void* args)
{
serv_t* p_serv = (serv_t*)args;
bool thread_client_connected;
int thread_client_fd;
while(p_serv->b_running)
{
pthread_mutex_lock(&(p_serv->new_connection_fd_lock));
while (0 == p_serv->new_connection_fd && p_serv->b_running)
{
pthread_cond_wait(&(p_serv->new_connection),
&(p_serv->new_connection_fd_lock));
}
thread_client_fd = p_serv->new_connection_fd;
p_serv->new_connection_fd = 0;
pthread_mutex_unlock(&(p_serv->new_connection_fd_lock));
// In the case of a pthread cond broadcast for exiting the server.
//
if (0 == thread_client_fd)
{
continue;
}
thread_client_connected = true;
while (thread_client_connected)
{
thread_client_connected = handle_client(thread_client_fd);
}
close(thread_client_fd);
thread_client_fd = 0;
sem_post(&(p_serv->client_count_sem));
}
return NULL;
} /* thread_handler */
Just for data reference here is my serv_t struct:
typedef struct serv_t {
bool b_running;
int max_connections;
int serv_listener_fd;
sem_t client_count_sem;
pthread_mutex_t new_connection_fd_lock;
pthread_cond_t new_connection;
int new_connection_fd;
pthread_t* p_thread_ids;
} serv_t;
Basically, if I run netcat or a client program I have against it with multiple instances via a bash command to "background" the application, some of these instances get stuck. I have it redirecting the output to a file, but what's happening is that particular instance of the client/netcat is just getting stuck after the accept call.
More specifically, if I run my program with two threads, one instance of a program gets stuck and no subsequent copies get stuck, even running 6500 instances against the server.
If I run it with ten threads, as many as 8 or 9 instances get stuck, but the threads still function properly within the server.
EDIT:
Client code I refer to, starting from the server letting the client know that the server is ready to receive data:
char buff[2] = { 0 };
err = recv(client_socket_fd, buff, 1, 0);
if ('0' != buff[0] && 1 != err)
{
fprintf(stderr,
"Server handshake error. [%s]\n",
strerror(errno));
close(client_socket_fd);
return EXIT_FAILURE;
}
if (NULL != p_infix_string)
{
if (MAX_BUFFER_SIZE < strlen(p_infix_string))
{
fprintf(stderr,
"Infix string is over 100 characters long.\n");
return EXIT_FAILURE;
}
errno = 0;
char* p_postfix = infix_to_postfix(p_infix_string);
if (EINVAL == errno || NULL == p_postfix)
{
fprintf(stderr, "Error converting provided string.\n");
}
bool success = send_postfix(p_postfix, client_socket_fd);
free(p_postfix);
if (false == success)
{
fprintf(stderr,
"An error occured while sending the equation to the server.\n");
close(client_socket_fd);
return EXIT_FAILURE;
}
}
The client is getting stuck at the receive call here:
bool send_postfix(char* p_postfix, int client_socket_fd)
{
if (NULL == p_postfix)
{
fprintf(stderr, "No postfix string provided to send to server.\n");
return false;
}
printf("Sending postfix to server\n");
int err = send(client_socket_fd,
p_postfix,
strnlen(p_postfix, MAX_BUFFER_SIZE),
0);
if(strnlen(p_postfix, MAX_BUFFER_SIZE) > err)
{
fprintf(stderr,
"Unable to send message to server. [%s]\n",
strerror(errno));
return false;
}
char response[MAX_BUFFER_SIZE] = { 0 };
printf("Waiting for receive\n");
err = recv(client_socket_fd, &response, MAX_BUFFER_SIZE, 0);
if (0 == err)
{
fprintf(stderr,
"Connection to server lost. [%s]\n",
strerror(errno));
return false;
}
else if (0 > err)
{
fprintf(stderr,
"Unable to receive message on socket. [%s]\n",
strerror(errno));
return false;
}
printf("Server responded with: \n%s\n", response);
return true;
} /* send_postfix */
EDIT: https://github.com/TheStaplergun/Problem-Code
I uploaded the code to this repo and removed the need for the extraneous files I use and filled them with placeholders.
You can recreate this problem using the server with the command ./postfix_server -p 8888 -n 2 and the client issue in another terminal with for i in {1..4}; do ./postfix_client -i 127.0.0.1 -p 8888 -e "3 + $i" &> $i.txt & done
The output of each client will be forcefully flushed because of the setbuf at the top of client. Run it, see if any programs hang, if not run that command again. Just type PS and see if one of them is hanging, and look at the resulting text file. You will see it is stuck at the receive call.
If you sigint the server (CTRL + C), the client that was stuck will close with a Connection reset by peer response from the server, so the server still does have that file descriptor locked up somewhere.
I believe a race condition is happening somehow, because it only happens randomly.
A curious thing is it only happens ONCE PER SERVER INSTANCE.
If I kill that hung instance and proceed to do it again 10000 times it never does another hang until the server is reset.
For some reason, even with the following code flow inside of the
server, some clients "Fall through the cracks" and get stuck in limbo.
(They never get handled by the server so they just hang after
accepting the connection)
There may be other issues, but the first one I see is that main loop does not ensure that a new connection is actually picked up by any handler thread before it tries to hand off the next connection. Even if there are handler threads already blocked on the CV when a new connection is accepted, it is possible for the main server thread to signal the CV, loop back around, accept another connection, reacquire the mutex, and overwrite the new-connection FD before any handler thread picks up the previous one. The chances of that increase if you have more threads than cores.
Note that that will also interfere with your semaphore-based counting of available handlers -- you decrement the semaphore for every semaphore accepted, but you increment it again only for those that are successfully handled.
There are various ways that you could make the main server thread wait for the new connection to be picked up by a handler. One group would involve the server waiting on a CV itself, and relying on a handler to signal it after picking up the connection. Another, perhaps simpler, approach would involve using a semaphore to similar effect. But I would suggest instead not waiting, but instead creating a thread-safe queue for available connections, so that the server doesn't have to wait. That would even allow for queueing more connections than presently available handlers, if that would be useful to you.

Linux Device Driver, kernel thread can't open file?

I'm writing a Linux Driver with Linux Kernel Modules when, user can write and when user calls close, driver has to flush content into a file in another directory with same name of the device file.
I have this problem: when a process calls close, the driver can open a file and flush all its content correctly; when the process is killed (for example, from the terminal with a kill), device driver fails to execute filp_open becuse fs->CURRENT is set to NULL. So, I was trying to start a kernel thread to do this work.
When I try opening a file in the same directory, for example filp_open("myfile"...), it works correctly. But if I have to open a file in another directory, so filp_open("dirA/myfile"), filp_open returns -2. But this not going to happen when I call filp_open from the main thread.
This is my code:
static int thread_fn(void *unused){
struct thread_data* td = (struct thread_data *) unused;
if(td == NULL)
printk(KERN_INFO "td is null\n");
struct file* filp=filp_open("/dirA/myfile",O_RDWR,0666);
if(filp == NULL || (IS_ERR(filp)))
printk(KERN_INFO "filp is null!\n");
else
printk(KERN_INFO "filp is not null!\n");
size_t filp_size = filp->f_inode->i_size;
printk(KERN_INFO "size on release: %ld\n",filp_size);
if(filp_size > td->size){
printk(KERN_INFO "truncating file\n");
truncate_setsize(filp->f_inode, td->size);
}
inode_lock(filp->f_inode);
//file_write(filp,/*file->f_pos*/0,td->data,td->size);
inode_unlock(filp->f_inode);
printk(KERN_INFO "Thread Stopping\n");
do_exit(0);
return 0;
}
This is my device_release function:
static int device_release(struct inode *inode, struct file *file)
{
if(my_data->buffer == NULL)
return -ENOMEM;
struct thread_data* td=alloc_mem(sizeof(struct thread_data));
td->filename=my_data->filename;
td->data=my_data->buffer;
td->size=my_data->size;
thread_st = kthread_run(thread_fn, (void *)td,"Thread!");
if (thread_st)
printk(KERN_INFO "Thread Created successfully\n");
else
printk(KERN_ERR "Thread creation failed\n");
return 0;
}
What's the problem? I can't understand, it could be an OS problem? I have also tried with set_fs/get_fs but it didn't work.
I have an update: if I put flag O_CREAT, filp_open doesn't return error, but file isn't created; so, kernel thread cannot operate on file?

How are reboot handle when a process is still running

Here's the situation. I'm debugging a code to do a logging function. When the user log in, the log file will be create with .part format. This file is save locally inside the host. I do not know why it's name as .part. When the user finish their session, the log file will be rename as .username only. Beside the local log file, this code is also connected to a server where this server will also save the logging file. The problem is when the logging is still running, but the host suddenly reboot. The reboot might be caused by command from root, or a force reboot, or maybe a hardware fault. This causes the logging file to stay as .part and the server also follows.
So, my question is:
How to make it rename the file before the process is killed or terminated during reboot?
Whats the signal that I should handle?
I'm thinking this might involve a race condition, is there a way for me to delay the reboot?
My approach
tried to handle SIGPWR,SIGSTOP,SIGTERM,SIGQUIT
create a bash script to do renaming when the process start.
Here is the main code:
int main(int argc, char **argv)
{
int ch;
int NoFork = 0;
struct event_config *evconfig;
struct event *signal_event_int;
struct event *signal_event_quit;
struct event *signal_event_term;
struct event *signal_event_hup;
struct event *signal_event_chld;
struct event *signal_event_pwr;
struct event *signal_event_stop;
syspath_init_from_argv0(argv[0]);
load_config(); /* load config first, the command line parameters will override */
event_set_log_callback(my_event_log_cb);
evconfig = event_config_new();
if (event_config_require_features(evconfig, EV_FEATURE_FDS)!=0) {
log_error("event_config_require_features_failed");
}
while (!done) {
/* ignore HUP first, just in case someone send us a HUP
when we are reloading config, that will create a condition
that makes us exit, with HangUp */
sig_catch(SIGHUP,SIG_IGN);
base = event_base_new_with_config(evconfig);
local_listener = create_local_listener(base);
if (!local_listener) {
log_error("Could not create a local listener!");
return 1;
}
http_listener = create_http_listener();
if (!http_listener) {
log_error("Could not create a remote listener!");
return 1;
}
evhttp_set_cb(http_listener, "/mrexec", http_mrexec_cb, NULL);
if (options.accept_remote) {
evhttp_set_cb(http_listener, "/rlog", http_rlog_cb, NULL);
}
if (pidfile_create(ACTSLOGD_PIDFILE)==-1) {
log_error("pidfile_create:failed:%d:%s", errno, strerror(errno));
}
LIST_INIT(&clientlist);
if (options.log_remote) {
start_log_remote();
}
signal_event_int = evsignal_new(base, SIGINT, exit_cb, (void *)base);
event_add(signal_event_int, NULL);
signal_event_quit = evsignal_new(base, SIGQUIT, exit_cb, (void *)base);
event_add(signal_event_quit, NULL);
signal_event_term = evsignal_new(base, SIGTERM, exit_cb, (void *)base);
event_add(signal_event_term, NULL);
signal_event_hup = evsignal_new(base, SIGHUP, reload_config_cb, (void *)base);
event_add(signal_event_hup, NULL);
signal_event_chld = evsignal_new(base, SIGCHLD, sigchld_cb, (void *)base);
event_add(signal_event_chld, NULL);
signal_event_pwr = evsignal_new(base, SIGPWR, power_off_cb, (void *)base);
event_add(signal_event_pwr, NULL);
signal_event_stop = evsignal_new(base, SIGSTOP, power_off_cb, (void *)base);
event_add(signal_event_chld, NULL);
actslog_event_start(AGENT_ACTSLOGD);
actslog_event_start(AGENT_ESCALATED);
event_base_dispatch(base);
printf("finished dispatch\n");
evconnlistener_free(local_listener);
evhttp_free(http_listener);
http_listener = NULL;
event_free(signal_event_int);
event_free(signal_event_quit);
event_free(signal_event_term);
event_free(signal_event_hup);
event_free(signal_event_pwr);
event_free(signal_event_stop);
if (options.log_remote) {
end_log_remote();
}
event_base_free(base);
if (!done) {
load_config();
}
while (clientlist.lh_first != NULL) {
struct bufferevent *bev = clientlist.lh_first->bev;
bufferevent_free(bev);
LIST_REMOVE(clientlist.lh_first, clients);
}
}
if (rlog) {
rlog_close(rlog);
}
unlink(PATH_ACTSLOG);
pidfile_cleanup(ACTSLOGD_PIDFILE);
return 0;
}
This is the signal handler
static void exit_cb(evutil_socket_t sig, short events, void *user_data)
{
struct event_base *base = user_data;
struct timeval delay = { 2, 0 };
actslog_event_stop(AGENT_ACTSLOGD);
actslog_event_stop(AGENT_ESCALATED);
done = 1; //when this is 1, there is a function that will connect to the server to tell that the logging is stopped.
/* need to give some delay for us to send out the stop message to Logger */
event_base_loopexit(base, &delay);
}
static void power_off_cb(evutil_socket_t sig, short events, void *user_data)
{
struct event_base *base = user_data;
struct timeval delay = { 5, 0 };
char logfile_partial[MAXPATHLEN];
char logfile_complete[MAXPATHLEN];
char id[1024];
done =1;
event_base_loopexit(base,&delay);
snprintf(logfile_partial, //the logfile_partial will be the one with .part file
sizeof(logfile_partial),
"%s/SHELL.%s.part", logpath2, id);
snprintf(logfile_complete, //the logfile_complete will be the complete without .part
sizeof(logfile_complete),
"%s/SHELL.%s", logpath2, id);
if (rename(logfile_partial, logfile_complete)!=0) {
if (errno==ENOENT) {
int tmp;
log_error("mastershell [%s] log is incomplete", logfile_complete);
tmp = creat(logfile_complete, LOG_FILE_MODE);
if (tmp==-1) {
log_error("creat:%s:failed:%d:%s!!\n", logfile_complete, errno, strerror(errno));
} else {
close(tmp);
}
} else {
log_error("rename:%s:%s:failed:%d:%s!!\n", logfile_partial, logfile_complete, errno, strerror(errno));
}
}
if (rlog) {
rlog_close(rlog);
}
unlink(PATH_ACTSLOG);
pidfile_cleanup(ACTSLOGD_PIDFILE);
}
I have tested to handle all signal in exit_cb function. Also all signals inside power_off_cb function. Neither one of them works. I have tested on CentOS and Ubuntu. The logging process is a upstart process. Any comment or suggestion are really appreciated.
Here's the situation. I'm debugging a code to do a logging function.
When the user log in, the log file will be create with .part format.
This file is save locally inside the host. I do not know why it's name
as .part. When the user finish their session, the log file will be
rename as .username only. Beside the local log file, this code is also
connected to a server where this server will also save the logging
file. The problem is when the logging is still running, but the host
suddenly reboot. The reboot might be caused by command from root
If it is caused by a command from root you can handle it creating a script in /etc/init.d/.
, or a
force reboot, or maybe a hardware fault. This causes the logging file
to stay as .part and the server also follows.
You can't predict the future, neither the OS. If there is a reboot caused by a power or hardware failure there is no way to predict it.

Resources