struct sigaction incomplete error - c

Although including <signal.h> I get an error saying that struct sigaction is an incomplete type.
I have no Idea what to do with it.
Please help
#include <signal.h>
struct sigaction act;
int main(int argc, char** argv)
{
int depth;
/* validate arguments number*/
if(argc < 2)
{
printf("fatal error: please use arguments <MaxChild> <MaxDepth>\n");
exit(1);
}
/* register the realtime signal handler for sigchld*/
/*173*/
memset(&act,0,sizeof(act));
act.sa_handler = sigproc;
sigaction(SIGCHLD, /* signal number whose action will be changed */
&act, /* new action to do when SIGCHLD arrives*/
NULL); /* old action - not stored */
srand(time(NULL));
depth = rand() % atoi(argv[2]); /* [0 maxDepth]*/
RecursiveFunc(atoi(argv[1]), depth);
return 0;
}
The error messages:
proc.c: In function ‘main’:
proc.c:173:22: error: invalid application of ‘sizeof’ to incomplete type ‘struct sigaction’
proc.c:174:2: error: invalid use of undefined type ‘struct sigaction’
cc1: warnings being treated as errors
proc.c:175:2: error: implicit declaration of function ‘sigaction’

Just
#define _XOPEN_SOURCE 700
before any other line in your code, or compile with the -D option to define the preprocessor symbol
gcc ... -D_XOPEN_SOURCE=700 ...

I resolved this by changing the C standard that I was using with gcc.
I changed: gcc -std=c99 ...
to this: gcc -std=gnu99 ...

Related

What are ebpf BPF_HISTOGRAM and how create it | Error: a parameter list without types is only allowed in a function definition

I like to know what is HISTOGRAMS in EBPF.
So for example below ebpf program creates histogram
Compiling it cause warning then bunch of errors udp.c:7:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int] BPF_HISTOGRAM(counter, u64);
SO in this tutorial about XDP it tells to create histogram I need to do BPF_HISTOGRAM(counter, u64); so where BPF_HISTOGRAM is #defined. Also what needed to be a type specifier in above waring so if I am doing BPF_HISTOGRAM(counter, u64); so I am assuming it wil be expended to something like u64 counter so if thats the case there here u go I have type specifier than what else is it complaining about in clang command root#fawad:/home/fawad/bpf# clang -I /usr/include/x86_64-linux-gnu/ -O2 -Wall -target bpf -c udp.c -o udp.o
How how to get rid of these errors and a warning if I try to compile with above command
Errors like : IPPROTO_UDP not found
use of undeclared u64
use of undeclared counter,(if I am assuming right in above question text why this warning and error about counter and histogram)
So I have this simple code
#define KBUILD_MODNAME "udp_counter"
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>
BPF_HISTOGRAM(counter, u64);
int udp_counter(struct xdp_md *ctx)
{
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if ((void *)eth + sizeof(*eth) <= data_end)
{
struct iphdr *ip = data + sizeof(*eth);
if ((void *)ip + sizeof(*ip) <= data_end)
{
if (ip->protocol == IPPROTO_UDP)
{
struct udphdr *udp = (void *)ip + sizeof(*ip);
if ((void *)udp + sizeof(*udp) <= data_end)
{
u64 value = htons(udp->dest);
counter.increment(value);
}
}
}
}
return XDP_PASS;
}
Throws error
udp.c:7:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
BPF_HISTOGRAM(counter, u64);
^
udp.c:7:15: error: a parameter list without types is only allowed in a function definition
BPF_HISTOGRAM(counter, u64);
^
udp.c:22:33: error: use of undeclared identifier 'IPPROTO_UDP'
if (ip->protocol == IPPROTO_UDP)
^
udp.c:28:21: error: use of undeclared identifier 'u64'
u64 value = htons(udp->dest);
^
udp.c:29:21: error: use of undeclared identifier 'counter'
counter.increment(value);
^
udp.c:29:39: error: use of undeclared identifier 'value'
counter.increment(value);
^
1 warning and 5 errors generated.
root#fawad:/home/fawad/bpf# gedit udp.c
(gedit:7386): Gtk-WARNING **: 13:24:34.572
https://dev.to/satrobit/absolute-beginner-s-guide-to-bcc-xdp-and-ebpf-47oi

How do I use sigaction()? struct sigaction is not defined

I am doing simple sigaction example to practice C, but when I try to compile my code, it claims that struct sigaction doesn't exist [1].
When I checked out some old code I had produced I saw that I had added some POSIX string at the very top of the file [2]. But when I read the manual for sigaction (man 2 sigaction) there is nothing about _POSIX_SOURCE in it, the closest being _POSIX_C_SOURCE which doesn't work. How and when do I know which POSIX is the be used? When I try simple code that others have suggested, which is without the _POSIX_SOURCE it doesn't work.
[1]
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void sa_handler(int signum)
{
printf("The signal has been replaced with this useless
string!\n");
exit(0);
}
int main(void)
{
struct sigaction sa = {.sa_handler = sa_handler};
int sigret = sigaction(SIGINT, &sa, NULL);
while(1);
return 0;
}
[2]
#define _POSIX_SOURCE
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void sa_handler(int signum)
{
printf("The signal has been replaced with this useless
string!\n");
exit(0);
}
int main(void)
{
struct sigaction sa = {.sa_handler = sa_handler};
int sigret = sigaction(SIGINT, &sa, NULL);
while(1);
return 0;
}
When I compile the first example the result are these error messages.
sigaction.c: In function ‘main’:
sigaction.c:13:12: error: variable ‘sa’ has initializer but
incomplete type
struct sigaction sa = {.sa_handler = sa_handler};
^~~~~~~~~
sigaction.c:13:29: error: ‘struct sigaction’ has no member named
‘sa_handler’
struct sigaction sa = {.sa_handler = sa_handler};
^~~~~~~~~~
sigaction.c:13:42: warning: excess elements in struct initializer
struct sigaction sa = {.sa_handler = sa_handler};
^~~~~~~~~~
sigaction.c:13:42: note: (near initialization for ‘sa’)
sigaction.c:13:22: error: storage size of ‘sa’ isn’t known
struct sigaction sa = {.sa_handler = sa_handler};
^~
sigaction.c:14:18: warning: implicit declaration of function
‘sigaction’ [-Wimplicit-function-declaration]
int sigret = sigaction(SIGINT, &sa, NULL);
^~~~~~~~~
when I read the manual for sigaction (man 2 sigaction) there is nothing about _POSIX_SOURCE in it
From man sigaction:L
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
From future_test_macros(7):
_POSIX_SOURCE
Defining this obsolete macro with any value is equivalent to
defining _POSIX_C_SOURCE with the value 1.
Since this macro is obsolete, its usage is generally not doc‐
umented when discussing feature test macro requirements in
the man pages.
So _POSIX_SOURCE is equivalent to _POSIX_C_SOURCE 1 and is obsolete.
How and when do I know which POSIX is the be used?
From man future_test_macros:
Specification of feature test macro requirements in manual pages
When a function requires that a feature test macro is defined, the
manual page SYNOPSIS typically includes a note [....]
So you should check SYNOPSIS section in the manual page of the function/feature you are interested in. For example for man sigaction:
sigaction(): _POSIX_C_SOURCE
siginfo_t: _POSIX_C_SOURCE >= 199309L
So you need to define _POSIX_C_SOURCE for sigaction() and _POSIX_C_SOURCE greater or equal to the value of 199309 for siginfo_t.
You need to define a positive integer for _POSIX_C_SOURCE. For sigaction, it needs to be atleast:
#define _POSIX_C_SOURCE 199309L
Look the the documentation for which POSIX version to use.
You need to add <features.h> before <signals.>, as the features.h contains #define _POST_C_SOURCE with latest value for compatibility purpose.

File System in Userspace (FUSE) compilation error

/*This is a simple try to create a File System in UserSpace
The pre_init function just initializes the filesystem */
#include<linux/fuse.h>
#include<stdio.h>
#include<stdlib.h>
#include<fuse_lowlevel.h>
static void* pre_init(struct fuse_conn_info *conn, struct fuse_config *cfg){
printf("[init] called\n");
(void) conn;
return NULL;
}
static struct fuse_operations opr = {
.init = pre_init,
};
int main(int argc, char *argv[]){
return fuse_main(argc, argv, &opr, NULL);
}
I am trying to compile the code using gcc sample.c -o sample `pkg-config fuse --cflags --libs` And I'm getting a whole lot of errors in the code as i have shown
sample.c:7:59: warning: ‘struct fuse_config’ declared inside parameter list will not be visible outside of this definition or declaration
static void* pre_init(struct fuse_conn_info *conn, struct fuse_config *cfg){
^~~~~~~~~~~
sample.c:12:15: error: variable ‘opr’ has initializer but incomplete type
static struct fuse_operations opr = {
^~~~~~~~~~~~~~~
sample.c:13:3: error: ‘struct fuse_operations’ has no member named ‘init’
.init = pre_init,
^~~~
sample.c:13:10: warning: excess elements in struct initializer
.init = pre_init,
^~~~~~~~
sample.c:13:10: note: (near initialization for ‘opr’)
sample.c: In function ‘main’:
sample.c:16:9: warning: implicit declaration of function ‘fuse_main’; did you mean ‘fuse_mount’? [-Wimplicit-function-declaration]
return fuse_main(argc, argv, &opr, NULL);
^~~~~~~~~
fuse_mount
sample.c: At top level:
sample.c:12:31: error: storage size of ‘opr’ isn’t known
static struct fuse_operations opr = {
^~~
I have also checked that fuse is installed properly as the header files have been included without any issues. But why am I not able to compile this simple code?
There are two "fuse" versions, sometimes coexistent with each other: fuse2 and fuse3. And they differ. In my Archlinux there are two fuse packages: fuse2 and fuse3. On my system, file /usr/include/fuse.h just includes fuse/fuse.h and fuse/fuse.h comes from fuse2 packages. Header fuse3/fuse.h comes from fuse3.
Anyway, you want to use fuse3 api here as you use struct fuse_config. fuse3 defines struct fuse_config.
But, thirst of all, define FUSE_USE_VERSION macro before including any of the fuse header files, as specified in the beginning in fuse.h from fuse2 and in the fuse.h from fuse3:
IMPORTANT: you should define FUSE_USE_VERSION before including this header.
The following compiles with no warnings/errors using gcc -Wall -pedantic -lfuse3 1.c on my platform:
#define FUSE_USE_VERSION 31
#include <fuse3/fuse.h>
#include <stdio.h>
#include <stdlib.h>
static void* pre_init(struct fuse_conn_info *conn, struct fuse_config *cfg){
printf("[init] called\n");
(void) conn;
return NULL;
}
static struct fuse_operations opr = {
.init = pre_init,
};
int main(int argc, char *argv[]){
return fuse_main(argc, argv, &opr, NULL);
}

Defining external function (module) in the header file in C

When I compile the program, outlined below, I am getting the following error(s) back
[igor#localhost ~/I2C]$ make i2c_VIPER DEFINE=-DVIPER
gcc -g -Wall -D__USE_FIXED_PROTOTYPES__ -DVIPER -ansi -lusb -c -o i2c.o i2c.c
In file included from i2c.c:9:
viperboard.h:120: error: expected ‘)’ before ‘*’ token
i2c.c: In function ‘main’:
i2c.c:32: error: ‘usb_dev’ undeclared (first use in this function)
i2c.c:32: error: (Each undeclared identifier is reported only once
i2c.c:32: error: for each function it appears in.)
i2c.c:33: warning: implicit declaration of function ‘i2c_VIPER’
make: *** [i2c.o] Error 1
I've tried many things, more or less semi-blindly, to make it working. The struct parsed_CLI_I2C_t defined by me, works flawlessly. No compilation errors. But, when I try to use struct usb_device from <usb.h> in equivalent way, the compiler is not happy.
What I am doing wrong ?
Relatively detailed description follows.
Let's start with a code snippet from the standard #include < usb.h > <-- link to the full header file
/* Data types */
struct usb_device;
struct usb_bus;
struct usb_device {
struct usb_device *next, *prev;
char filename[PATH_MAX + 1];
struct usb_bus *bus;
struct usb_device_descriptor descriptor;
struct usb_config_descriptor *config;
void *dev; /* Darwin support */
u_int8_t devnum;
unsigned char num_children;
struct usb_device **children;
};
Here is the first local header file #include "viperboard.h"
struct parsed_CLI_I2C_t;
extern int i2c_VIPER (struct usb_device **usb_dev, struct parsed_CLI_I2C_t **CLI_I2C_options);
extern bool OpenDevice(void);
This is the second local header file #include "I2C.h"
typedef struct
{
char *USB_board;
int query;
int write_type;
} parsed_CLI_I2C_t;
extern int parse_CLI_I2C_options (int argc, char *argv[], parsed_CLI_I2C_t **CLI_I2C_options);
The main program looks like this
/* all other standard include stuff skipped for brevity */
#include <usb.h>
#include "viperboard.h"
#include <stdbool.h>
#include "I2C.h"
int main(int argc, char *argv[])
{
parsed_CLI_I2C_t *CLI_I2C_options;
parse_CLI_I2C_options (argc, argv, &CLI_I2C_options);
struct usb_device *usb_dev;
i2c_VIPER (&usb_dev, &CLI_I2C_options);
}
and, finally, this is the external module
i2c_VIPER.c
/* all other standard include stuff skipped for brevity */
#include <usb.h>
#include "viperboard.h"
#include <stdbool.h>
#include "I2C.h"
int i2c_VIPER (struct usb_device **usb_dev, struct parsed_CLI_I2C_t **CLI_I2C_options )
{
bool connected; /* True if the ViperBoard is connected */
connected = OpenDevice();
return(0);
}
This is
OpenDevice.c
#include <stdbool.h>
#include <usb.h>
bool OpenDevice() /* <---- this is line 11 */
{
usb_set_debug( 0 );
/* Initialize USB library */
usb_init( );
etc etc etc
return true;
}
========================================================
30 minutes later: all suggested changes implemented
Another type of error appeared.
OpenDevice.c:11: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘OpenDevice’
make: *** [OpenDevice.o] Error 1
This line
usb_device *usb_dev; /* this is line 32 */
will not work as you're compiling a C program, not a C++ program. In C structures are not automatically types like they are in C++. You need to use the struct keyword to declare structures:
struct usb_device *usb_dev; /* this is line 32 */
This change you have to do for every place where you use structures, for example like the declaration and definition of the i2c_VIPER function.
Also note that for the bool type to work, you need to include <stdbool.h>.

why am i not able to declare sigset_t with std=c99?

If i compile the below program with std=c99, i get an error, but the program compiles fine without the c99 flag. Why?
#include <signal.h>
void x()
{
sigset_t dd;
}
int main(void)
{
x();
return 0;
}
jim#cola temp]$ gcc -std=c99 blah.c -o blah
blah.c: In function ‘x’:
blah.c:9: error: ‘sigset_t’ undeclared (first use in this function)
blah.c:9: error: (Each undeclared identifier is reported only once
blah.c:9: error: for each function it appears in.)
blah.c:9: error: expected ‘;’ before ‘dd’
Because sigset_t is not part of <signal.h> in standard C and you requested strict standards compatibility with -std=c99. That is, a strictly standard C program can do:
#include <signal.h>
int sigset_t;
int main(void) { return 0; }
and expect it to work.
sigset_t is not in C99 standard, but it is available in POSIX. You can define _POSIX_SOURCE or _POSIX_C_SOURCE to make sigset_t available.
Here is the definition:
#define _NSIG 64
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef unsigned long old_sigset_t; /* at least 32 bits */
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
Also see What does #define _POSIX_SOURCE mean?

Resources