I am trying to write a custom plugin in C for collectd and cannot get it to compile with collectd. I've tried this tutorial and could get the plugin to work with the collectd build system.
I've also tried this with just a copy of the load plugin, and tried to manually compile the c-file in order to just link the compiled library (kind of a hackish way around). But I'm still getting errors.
When I run
gcc -I. -g -O -c load_copy.c -lcommon
I get this error
daemon/common.h:308:2: error: #error "Don't know how to convert between host
and network representation of doubles."
#error
\
^
daemon/common.h:336:23: warning: ‘struct passwd’ declared inside parameter list
struct passwd **pwbufp);
^
daemon/common.h:336:23: warning: its scope is only this definition or declaration, which is probably not what you want
load_copy.c: In function ‘load_read’:
load_copy.c:184:2: error: #error "No applicable input method."
#error "No applicable input method."
like there is still a compilation error. Has anyone successfully written a C plugin for collectd? Any tips?
This is from common.h
#ifdef HAVE_LIBKSTAT
int get_kstat(kstat_t **ksp_ptr, char *module, int instance, char *name);
long long get_kstat_value(kstat_t *ksp, char *name);
#endif
#ifndef HAVE_HTONLL
unsigned long long ntohll(unsigned long long n);
unsigned long long htonll(unsigned long long n);
#endif
#if FP_LAYOUT_NEED_NOTHING
#define ntohd(d) (d)
#define htond(d) (d)
#elif FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP
double ntohd(double d);
double htond(double d);
#else
#error \
"Don't know how to convert between host and network representation of
doubles."
#endif
Related
I plan on building several libraries following the FIPS standards (hashing, encryption). I want to have several batch/bash scripts that will automate the building process of these libraries for every desktop platforms (Windows, Mac, Linux). I plan on using MinGW's port of gcc on Windows and simply gcc on Linux or Mac.
My code for the library is the following:
hash.h
#ifndef HASHH
#define HASHH
#ifdef STATIC
#define ADDAPI
#define ADDCALL
#define EXTERN extern
#else
#define EXTERN
#ifdef _WIN32
#ifdef BUILD
#define ADDAPI __declspec(dllexport)
#else
#define ADDAPI __declspec(dllimport)
#endif
#define ADDCALL __cdecl
#else
#define ADDAPI
#define ADDCALL
#endif
#endif
/*** The sha3-256 hash function.
#param buffer The buffer containing the data to be hashed.
#param length The length of the buffer.
#param digest The hash of the data in buffer.
*/
ADDAPI EXTERN int ADDCALL sha3_256(unsigned char* buf, unsigned long len, unsigned char* digest);
#endif
hash.c
#include "hash.h"
int sha3_256(unsigned char* buf, unsigned long len, unsigned char* digest){
return len * 2;
}
For DLL target on Windows I do:
gcc -c -D BUILD source\hash.c -oobjects\hash.o
ld -s -shared objects\hash.o -ohash.dll
For static target I do:
gcc -c -D STATIC source\hash.c -oobjects\hash.o
ar rcs hash.lib objects\hash.o
Everything works fine for building but when I use the header in a program the ADDAPI and ADDCALL macros are never defined for static building. This is due to the STATIC macro never initialized. I would like that this same header works for both building and using in client apps. I would also like that the macros allow to build both for dll target than for static lib target without the client having to pass a macro on the command line for it to work.
Do you have any idea if this is possible?
If it is, how would you go about doing this?
With the above code both building static and dll works but for client only dll works because for static I need to pass the STATIC macro on the command line. I want an option to prevent that.
I'm new to linux.
I'm practice syscall and I want to copy struct to user.
So I write a syscall which is using copy_to_user().
But When I write and compile test.c to test my syscall appear some error.
in linux/sched.h has defined:
struct pacct_struct {
int ac_flag;
long ac_exitcode;
unsigned long ac_mem;
cputime_t ac_utime, ac_stime;
unsigned long ac_minflt, ac_majflt;
};
and then I write a program that use this struct(test.c)
#include "linux/sched.h"
#include <stdlib.h>
int main(){
struct pacct_struct *ts;
ts = (struct pacct_struct *)malloc(sizeof(struct pacct_struct));
return 0;
}
and gcc show the follow error message:
test.c:6:44: error: invalid application of 'sizeof' to incomplete type 'struct pacct_struct'
I wonder to know if it's fine to use kernel struct by include header file.
If so, do I miss something? How to make pacct_struct become a 'complete type'?
thanks.
addition:
I check preprocessor with gcc -E
I found that seems no "struct pacct_struct" being included.
Next, I going to view sched.h that I included which was created by "make headers_install" after I compile the kernel.
The file only contains some cloning flags such like "#define CSIGNAL 0x000000ff"
So, I tried to include original source file of sched.h in dir "/usr/src/linux-2.6.39.4/include/linux", but it continue showing same error 'incomplete type'.
Then I check preprocessor again.
I still can't find 'struct pacct_struct' even I include original header file
Anything in sched.h after #ifdef __KERNEL__ is disappear, What happened?
I'm working on a smart meter project, ARM, keil compiler. I want to compile some of the more complex logic under g++ to run regression tests. I'm having a problem with some include files defining the interface to WMBus stack we purchased.
PACKED_STRUCT( typedef struct S_WMBUS_ADDR_T
{
/*! Manufacturer ID */
uint8_t pc_manufr[WMBUS_ADDR_MANUFR_LEN];
/*! Ident number */
uint8_t pc_ident[WMBUS_ADDR_IDENT_LEN];
/*! Version */
uint8_t c_version;
/*! Type */
uint8_t c_type;
}, s_wmbus_addr_t);
PACKED_STRUCT is defined in a compiler sensitive include file:
#elif defined (__GNUC__)
#define PACKED_STRUCT(__declaration__, __name__) \
__declaration__ __attribute__ ((__packed__)) __name__
...
#elif defined(__arm__)
#ifdef __ARMCC_VERSION
#define PACKED_STRUCT(__declaration__, __name__) \
__packed __declaration__ __name__
And I always get the following error messages:
error: types may not be defined in parameter types
error: typedef declaration invalid in parameter declaration
I can so no way around this other than by editing the include file to remove the PACKED_STRUCT. Obviously I won't edit the files directly, I'll copy them, edit them, and use the -I directive to make it find my modified files under G++
The error message seems to be saying you cannot declare a type as an argument to a macro?
Note even if I redeclare:
#define PACKED_STRUCT(__declaration__, __name__) \
__declaration__ __name__
I am using the -std=c++11 flag to g++ but removing this flag solves nothing, but makes a system include fail
Is there any way I can define PACKED_STRUCT to make the unmodified code compile under g++?
#LP You are right, though I'm not sure why right now. This code compiles:
I must have a wrong include file slipping through somehow.
typedef unsigned char uint8_t;
#define WMBUS_ADDR_MANUFR_LEN 4
#define WMBUS_ADDR_IDENT_LEN 4
#define PACKED_STRUCT(__declaration__, __name__) \
__declaration__ __attribute__ ((__packed__)) __name__
PACKED_STRUCT( typedef struct S_WMBUS_ADDR_T
{
/*! Manufacturer ID */
uint8_t pc_manufr[WMBUS_ADDR_MANUFR_LEN];
/*! Ident number */
uint8_t pc_ident[WMBUS_ADDR_IDENT_LEN];
/*! Version */
uint8_t c_version;
/*! Type */
uint8_t c_type;
}, s_wmbus_addr_t);
s_wmbus_addr_t hello;
I'm new to C and had some questions around struct instantiation. I have two files :
Index.c : which instantiates a new Server struct
server/Server.c which defines the Server struct, the new_Server() constructor and the kill_Server() deconstructor
Content of Index.c :
/* Standard libraries */
#include <stdio.h>
#include <string.h>
/* Project's Custom classes */
#include "./server/Server.c"
/* Configuration value */
#define HOST "127.0.0.1"
#define PORT 80
int main (void) {
unsigned short port = PORT;
unsigned char host[255] = HOST;
Server* server = new_Server(port, host);
return 0;
}
Content of server/Server.c :
#include <stdlib.h>
/* HOST_NAME_MAX will have to be changed into getconf HOST_NAME_MAX */
#define HOST_NAME_MAX 255
typedef struct {
unsigned short port;
unsigned char host[HOST_NAME_MAX];
} Server;
Server* new_Server (unsigned short port, unsigned char host[]) {
Server* server = malloc(sizeof(Server));
server->port = port;
server->host = host;
return server;
}
void kill_Server (Server* server) {
free(server);
}
When I compile the program, I get the following output :
In file included from src/index.c:6:
src/./server/Server.c:11:9: warning: no previous prototype for function 'new_Server' [-Wmissing-prototypes]
Server* new_Server (unsigned short port, unsigned char host[]) {
^
src/./server/Server.c:14:15: error: array type 'unsigned char [255]' is not assignable
server->host = host;
~~~~~~~~~~~~ ^
src/./server/Server.c:18:6: warning: no previous prototype for function 'kill_Server' [-Wmissing-prototypes]
void kill_Server (Server* server) {
^
2 warnings and 1 error generated.
(I just left out the "server" variable not used warning.)
So here are my questions :
Why am I getting the "missing prototype" warning since I actually did specify the output and method argument types ?
How can I initialise a struct with it's "host" key being an array of chars ?
Is what I'm doing efficient ? Steps :
configure values in a #define
create the corresponding variables
passing them as constructor parameters
initialise a struct instance
assign the value to it's associated key
I read that to get the maximum hostname size you should do "getconf HOST_NAME_MAX". In the shell it works of course and I get 255, but I'd like to store the value in a variable in my C program.
How can I achieve this ?
I'm compiling with the following GCC flags :
gcc -g -O0 -Wall -Wextra -std=c89 -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wold-style-definition -Wdeclaration-after-statement
I know this is (unnecessarily) strict, but I'd like to learn C the hard way and really understand it's ins-and-outs. And I think that stuff like warnings are great for this.
EDIT: I did already read this question How to initialize a structure with flexible array member, but I didn't really understand the answer. It also leaves out the issue about method prototypes.
Well, you should avoid using #include to include a .c file. The .c files are supposed to be compiled separately (with common definitions in a .h file that both include), and then you link the compiled objects together.
The two warnings is bogus, there is no code problem. You could suppress the warning by adding a prototype (just copy line 11 but put a ; on the end). Same for the second one
The error: server->host = host; is illegal. Arrays are second-class citizens in C, you cannot copy them using the = operator. You need to either go memcpy(&server->host, &host, sizeof server->host);, or strcpy(server->host, host);.
I think it'd be overkill to have your C program execute getconf and see what it got; instead, look up what the max value is that getconf will ever give back to you.
I'm compiling grep on the 64-bit GCC compiler for Windows 7 x64 SUA/Interix.
It chokes on the marked line in stddef.h:
#ifndef _SIZE_T_DEFINED
#if defined (lp64) || defined(_WIN64)
#ifdef lp64
typedef unsigned long size_t; // <------ error
#else /* lp64 */
typedef unsigned __int64 size_t;
#endif /* lp64 */
#else /* (defined(lp64) || defined(_WIN64)) */
typedef unsigned int size_t;
#endif /* (defined(lp64) || defined(_WIN64)) */
#define _SIZE_T_DEFINED
#define _SIZE_T
#endif /* _SIZE_T_DEFINED */
The output for make is:
make all-recursive
Making all in intl
gcc -c -DLOCALEDIR=\"/usr/local/share/locale\" -DLOCALE_ALIAS_PATH=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DIN_LIBINTL -DHAVE_CONFIG_H -I.. -I. -I../../intl -D_ALL_SOURCE -D_REENTRANT -I/usr/local/include -I/usr/local/include -D_ALL_SOURCE -D_REENTRANT ../../intl/intl-compat.c
In file included from ../../intl/gettextP.h:23:0,
from ../../intl/intl-compat.c:25:
/usr/include/stddef.h:50:23: error: duplicate 'unsigned'
*** Error code 1
Stop in /tmp/grep-2.5.4-src/build/intl.
*** Error code 1
Stop in /tmp/grep-2.5.4-src/build (line 329 of Makefile).
*** Error code 1
Stop in /tmp/grep-2.5.4-src/build (line 244 of Makefile).
I don't understand what the cause is... it's already confusing that long is being used as though it's 64-bit in GCC, but the error is even more confusing! Ideas?
Somewhere in your code, somone probably did:
#define size_t unsigned long
Or something along those lines, without having defined _SIZE_T_DEFINED when they did it. Then their code #includes stddef.h via the path listed in your error message. That makes your error line look like:
typedef unsigned long unsigned long;
To the compiler, which is not going to work!