I am trying to use libevent for manage the serial communication between an embedded Linux device and a pc.
First problem with libevent. I've created a C Project in eclipse , in the main I am creating some events and it is ok for the compiler:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <event.h>
#include "function_test.h"
....
int main(void) {
struct event ev_sighup; //reports that the user's terminal is disconnected
struct event ev_sigterm; //program termination
struct event ev_sigint; // program interrupt
int rv = 0;
/* Set up libevent & signal handling */
event_init();
event_set(&ev_sighup, SIGHUP, EV_SIGNAL, peripherals_end, NULL);
event_add(&ev_sighup, NULL);
event_set(&ev_sigterm, SIGTERM, EV_SIGNAL, peripherals_end, NULL);
event_add(&ev_sigterm, NULL);
event_set(&ev_sigint, SIGINT, EV_SIGNAL, peripherals_end, NULL);
event_add(&ev_sigint, NULL);
.....
}
But then, in "function_test.c":
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <event.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include "function_test.h"
.....
/*serial file descriptor */
int 232_fd= -1;
/* Event triggered when data is available */
struct event ev_rs232read;
.....
event_set(&ev_rs232read, 232_fd, EV_READ|EV_PERSIST, readRs232, NULL);
if ((rv = event_add(&stm32_ev_read, NULL)) < 0) {
// log error
return RTN_ERR;
}
return RTN_OK;
}
And misteriously Eclipse doesn't finds event.h (only in function_test.c) and thereby I got the next errors:
warning: implicit declaration of function ‘event_set’
../src/function_test.c:114: error: ‘EV_READ’ undeclared (first use in this function)
../src/function_test.c:114: error: (Each undeclared identifier is reported only once
../src/function_test.c:114: error: for each function it appears in.)
../src/function_test.c:114: error: ‘EV_PERSIST’ undeclared (first use in this function)
...
Does this bug repeats during the compilation with GNU Autotools or just simple Makefile?
Related
I'm trying to print 'error number' from errno.h in my_func. If i include <errno.h> in my_func.c directly everything is Ok. But if i include <errno.h> in "my_header.h" and then include "my_header.h" in my_func.c compiler spits out the error:
src/my_func.c: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'int (*(*)())' [-Wint-conversion]
return (print_errno(errno));
/usr/include/sys/errno.h:81:15: note: expanded from macro 'errno'
#define errno (*__error())
my_func.c:
#include "my_header.h"
int my_func(void)
{
if (write(5, "Hello, world!", 13) == -1)
return(print_errno(errno));
}
my_header.h:
#include <errno.h>
int print_errno(int errno);
print_errno.c:
#include "my_header.h"
#include <stdio.h>
int print_errno(int errno)
{
printf("error number = %d", errno);
return (-1);
}
Why do i have this error?
It's because you have named your parameter errno which is expanded by the preprocessor, due this
#define errno (*__error())
(errno.h)
So this prototype
int print_errno(int errno);
expands to
int print_errno(int (*__error()));
Short fix, don't call your parameter errno
I wanna add new system call at FreeBSD. My system call code is:
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/sysproto.h>
int Sum(int a, int b);
int
Sum(a,b)
{
int c;
c = a + b;
return (0);
}
But when I rebuild the kernel, I have an error:
What's wrong? Can you help me?
Thanks a lot.
Here's how I did it with my example system call of setkey which takes two unsigned ints.
I added my system call to the end /kern/syscalls.master
546 AUE_NULL STD { int setkey(unsigned int k0, unsigned int k1);}
Then I did
cd /usr/src
sudo make -C /sys/kern/ sysent
Next, I added the file to /sys/conf/files
kern/sys_setkey.c standard
My sys_setkey.c is as follows
#include <sys/sysproto.h>
#include <sys/proc.h>
//required for printf
#include <sys/types.h>
#include <sys/systm.h>
#ifndef _SYS_SYSPROTO_H_
struct setkey_args {
unsigned int k0;
unsigned int k1;
};
#endif
/* ARGSUSED */
int sys_setkey(struct thread *td, struct setkey_args *args)
{
printf("Hello, Kernel!\n");
return 0;
}
Also, I added the system call to /kern/capabilities.conf
##
## Allow associating SHA1 key with user
##
setkey
Finally, while in /usr/src/ I ran the command
sudo make -j8 kernel
sudo reboot
This is a program which runs the system call
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
int main(){
//syscall takes syscall.master offset,and the system call arguments
printf("out = %d\n",syscall(546,1,1));
return 0;
}
Please read this
I think, that you haven't included your file with sys_Sum function in kernel makefile ( notice, that in your code, that you have provided, function name is Sum and in error there is call to sys_Sum. I hope, that it's just a typo in your code and the name of function is sys_Sum ).
Is it possible to detect memory leaks or double free with Frama-c?
I have tried to test that example But
#include <string.h>
#include <stdlib.h>
#define FRAMA_C_MALLOC_STACK
#include "/usr/share/frama-c/libc/fc_runtime.c"
int main()
{
int *x = malloc(sizeof(int));
free(x);
free(x);
return 0;
}
I get :
Now I am using Version: Neon-20140301 and libc copied from Fluorine-20130601 ( btw why fc_runtime.c and other *.c files are deleted from Neon release ? )
command:
frama-c-gui -cpp-command "gcc -C -E -I/usrhare/frama-c/libc/ -nostdinc" -slevel 1000 -val -val-warn-copy-indeterminate #all main.
Using other defines (FRAMA_C_MALLOC_XXXX) works but is not detecting any bugs.
update:
Other example
#include <string.h>
#include <stdlib.h>
#define FRAMA_C_MALLOC_STACK
#include "/usr/share/frama-c/libc/fc_runtime.c"
int main()
{
int *x = malloc(sizeof(int));
x[2] = 5;
return 0;
}
I wrote a simple TCP/IP network applications (server and client). In the code of client app, I did like this and then build with 'g++ -o client client.cpp' under Linux.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char* argv[])
{
struct sockaddr_in server_addr;
struct hostent* host;
....
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(nPort);
server_addr.sin_addr = *((struct in_ddr*)host->h_addr); /*It complains as below while building*/
....
}
client.cpp: In function 'int main(int, char**)':
client.cpp:56: error: no match for 'operator=' in 'server_addr.sockaddr_in::sin_addr = *(in_ddr*)(* host->hostent::h_addr_list)'
/usr/include/netinet/in.h:138: note: candidates are: in_addr& in_addr::operator=(const in_addr&)
* Error code 1
clearmake: Error: Build script failed for "client"
what's going on with my implementaion?
You are trying to set an address list as a single address. You'll want to use brackets to refer to the address you want. host->h_addr_list[0]
At least that is what I am getting from your error.
Reference sources
How to change the value of the tos bits in the ip header?
I tried directly modifying it using the iphdr structure.
It is done at the kernel level using netfilter.
The code I wrote is as follows:
// Including the required header files
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <net/sock.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
// Defining the name of the module
#define MODULE_NAME "TOS_setter"
// Structure definition for processing outgoing packets
static struct nf_hook_ops nf_ops_out;
//===========================================================
// Function that modifies the TOS bits
unsigned int tos_setter(unsigned int hooknum,struct sk_buff *skb, const struct net_device *in,
const struct net_device *out,int (*okfn)(struct sk_buff*))
{
struct iphdr *iph;
unsigned char tosbits;
if (!skb)return NF_ACCEPT;
iph = ip_hdr(skb);
if (!iph)return NF_ACCEPT;
//if(iph->protocol==IPPROTO_TCP)return NF_ACCEPT;
if (iph->protocol==IPPROTO_TCP)
{
printk(KERN_ALERT " The total length is : %d\n" , (int)iph->tot_len);
iph->tos = tosbits | (unsigned char)2;
tosbits = iph->tos;
printk(KERN_ALERT " The tos bits are : %d\n" , (int)tosbits);
printk(KERN_ALERT " The total length is : %d\n" , (int)iph->tot_len);
}
return NF_ACCEPT;
}
//===========================================================
//Initialisation function
static int __init init(void){
printk(KERN_ALERT " Initialization Started \n");
// Initialize Hook Functions
nf_ops_out.hook = tos_setter;
nf_ops_out.pf = PF_INET;
nf_ops_out.hooknum =4;
nf_ops_out.priority = NF_IP_PRI_FIRST;
// Register the Hook functions
nf_register_hook(&nf_ops_out);
printk(KERN_ALERT "hook functions registered\n");
printk(KERN_ALERT " KSTAT Initialization Completed \n");
return 0;
}
static void __exit cleanup(void){
printk(KERN_ALERT "KSTAT Exit Started\n");
// Unregister the hook functions
nf_unregister_hook(&nf_ops_out);
printk("Unregistered the hooks\n");
printk(KERN_ALERT "KSTAT Exit Completed\n");
}
/* init and cleanup functions */
module_init(init);
module_exit(cleanup);
MODULE_LICENSE("GPL");
The problem is that when I try to change the value of the tos bits my internet stops working.
Is there any other way or if anyone can point out what i am doing wrong it will be really helpful.
You have to re-calculate the IP header checksum after you change anything in the header.
See WP: http://en.wikipedia.org/wiki/IPv4_header_checksum
Code is here: How do I compute an RFC 791 IP header checksum?
You can use incremental IP checksum, i.e: since the IP checksum is a sum, you can substract the old value and add the new one. Linux supports that with the csum_replace*() functions in net/checksum.h. Just do:
csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));