What I have to put as second parameter in this function? I need to understand the meaning of int (*fn)(const char *, const struct stat *ptr, int flag).
int
ftw(const char *path, int (*fn)(const char *, const struct stat *ptr, int flag),
int depth);
Thank you!!
int (*fn)(const char *, const struct stat *ptr, int flag)
is a pointer to a function that returns an int and takes a const char*, a const struct stat *, and an int.
If you had this function:
int func (const char *s, const struct stat *ptr, int flag)
{
return 0;
}
You could pass func as that argument.
Related
I am trying to port old C code from FreeBSD into Ubuntu. The code contains calls to some functions specific for old FreeBSD C-standard library (stdlib.h). What are the analogs of these functions in modern Linux library?
char *cgetcap (char *, char *, int);
int cgetclose (void);
int cgetent (char **, char **, char *);
int cgetfirst (char **, char **);
int cgetmatch (char *, char *);
int cgetnext (char **, char **);
int cgetnum (char *, char *, long *);
int cgetset (char *);
int cgetstr (char *, char *, char **);
int cgetustr (char *, char *, char **);
int strcasecmp (const char *, const char *);
I try to run a function with a structure, because I work with a module who send callback so I want to execute the fuction to anwser to the callback.
typedef void (*bgs2_e_rx_callback)(unsigned char reason, unsigned short int n, char * data);
void bgs_callbacktest(char* data);
/*void test(int* ptest);
void test_tab(char* data,char* ptaille);
char* concat(const char *s1, const char *s2);
static void parse_numeric_rsp(char nb_values, char * data, unsigned long data_len,unsigned long * result);*/
struct teststruct{
short int i ;
bgs2_e_rx_callback callback;
void* param;
};
struct teststruct leteststruct ;
int main(){
printf("test for function in structure\n");
char txt[]="i'm a text";
leteststruct.param = txt;
leteststruct.callback = &bgs_callbacktest;
}
void bgs_callbacktest(char* data){
printf("your text: %s\n",leteststruct.param);
}
Compilation works good, but I don't see the message of the callback function.
You never call it! Edit your main like this:
int main(){
printf("test for function in structure\n");
char txt[]="i'm a text";
leteststruct.param = txt;
leteststruct.callback = bgs_callbacktest;
// Change the dummy parameters below with yours
leteststruct.callback(0x7f, 512, txt);
}
Then you will have it.
I'm writing a Linux device drive and I'm confused as to why I'm getting this warning.
error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.write = file_write,
This is my code that I created, when I use make command I get the above error. I tried changing ssize_t to int but still I get the same error.
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/random.h>
MODULE_LICENSE("NIKS");
static char msg[100]={0};
static short readPos =0;
static int file_open(struct inode * , struct file *);
static int file_release(struct inode * , struct file *);
static ssize_t file_read(struct file *, char *, size_t,loff_t * );
static ssize_t file_write(struct file *, char *, size_t,loff_t * );
static struct file_operations fo =
{
.read = file_read,
.open = file_open,
.write = file_write,
.release = file_release,
};
int init_module(void)
{
int t = register_chrdev(150,"encdev",&fo);
if(t<0)
{
printk("error");
}
else
{
printk("success");
}
return t;
}
void cleanup_module(void)
{
unregister_chrdev(150,"encdev");
}
static int file_open(struct inode *in , struct file *fil)
{
return 0;
}
static ssize_t file_read(struct file *fil, char *buf, size_t len,loff_t *off )
{
short count=0;
printk("here %d",msg[0]!=0);
while(len && (msg[readPos]!=0))
{
printk("read");
put_user(msg[readPos],buf++);
count++;
len--;
readPos++;
}
return count;
}
static ssize_t file_write(struct file *fil, char *buf, size_t len,loff_t *off )
{
short ind = 0;
short count =0;
memset(msg,0,100);
readPos = 0;
int i =0;
char bytes[16];
char rand;
while(i<16)
{
get_random_bytes(&rand, sizeof(rand));
bytes[i]=rand;
++count;
i++;
}
int _len = len+16;
while(_len>0 || count%16){
if(ind<16) msg[ind] = bytes[ind];
else{
msg[ind] = (_len>0?buf[ind-16]:'#')^msg[ind-16];
}
++ind;
--_len;
++count;
}
return count;
}
static int file_release(struct inode *in , struct file *fil)
{
printk("done");
return 0;
}
I'm new to C and I just can't work out why I'm getting this warning. Can anybody explain why I get this warning and what to do about it please?
The correct types for the read and write function pointers of struct file_operations are:
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
Therefore, in your module, the appropriate signatures are:
static ssize_t file_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t file_write(struct file *, const char __user *, size_t, loff_t *);
// ...
static ssize_t file_read(struct file *fil, char __user *buf, size_t len,loff_t *off)
{
// ...
static ssize_t file_write(struct file *fil, const char __user *buf, size_t len, loff_t *off)
{
The important part that was missing was the const qualifier, but it's also important to remember that any pointer passed from userspace should be marked with the __user annotation (even though the compiler will not warn you if you forget it, it's only meant to be used as a static check for Sparse).
You also have several declarations after other stataments, which is invalid in C90. The compiler will warn you about those, follow the warnings and move them to the top of the function body.
I am trying to convert this example (found here) from the openssl documentation to work with LuaJIT's FFI. Scroll down for complete Lua code.
BIO *bio, *b64;
char message[] = "Hello World \n";
b64 = BIO_new(BIO_f_base64());
bio = BIO_new_fp(stdout, BIO_NOCLOSE);
BIO_push(b64, bio);
BIO_write(b64, message, strlen(message));
BIO_flush(b64);
BIO_free_all(b64);
But when I get to this line in the code ssl.BIO_flush(b64)I am getting the error below (running this from the LuaJIT interpreter and not a file)
stdin:1: Symbol not found: BIO_flush
stack traceback:
[C]: in function '__index'
stdin:1: in main chunk
[C]: at 0x0ac2cdd2f176
I understand that there are many other ways to do base64 encoding and at this point I have switched to a pure Lua solution. I still would like to understand why I'm getting this error because in part I'm working on this project to learn more about the LuaJIT FFI interface and openssl is already a dependency for libcurl which I am already using (hitting various APIs with OAth and I want to keep my dependencies as lean as possible).
I have already been successful at using openssl's HMAC() authentication function (found here) from LuaJIT's FFI so through reading documentation and trial and error I am pretty familiar with LuaJIT's FFI interface. Lua code below. I had to navigate through MANY openssl header files to get to this ffi.cdef[[]] but seems like maybe I'm still missing something. Any help would be appreciated.
EDIT: Just to test if the BIO_flush() is somehow optional, I've also excluded that line and gone all the way through my code with no errors but then I check the output file and it is blank.
ffi = require "ffi"
ffi.cdef[[
typedef struct bio_method_st BIO_METHOD;
typedef struct bio_st BIO;
typedef void bio_info_cb(BIO *, int, const char *, int, long, long);
struct crypto_ex_data_st { struct stack_st_void *sk; };
typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
typedef void CRYPTO_RWLOCK;
typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi,long argl, long ret);
typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp,size_t len, int argi,long argl, int ret, size_t *processed);
struct bio_st { const BIO_METHOD *method; BIO_callback_fn callback; BIO_callback_fn_ex callback_ex; char *cb_arg;int init; int shutdown; int flags;int retry_reason; int num; void *ptr; struct bio_st *next_bio;struct bio_st *prev_bio;int references; uint64_t num_read; uint64_t num_write; CRYPTO_EX_DATA ex_data; CRYPTO_RWLOCK *lock; };
struct bio_method_st { int type; const char *name; int (*bwrite) (BIO *, const char *, size_t, size_t *); int (*bwrite_old) (BIO *, const char *, int); int (*bread) (BIO *, char *, size_t, size_t *); int (*bread_old) (BIO *, char *, int); int (*bputs) (BIO *, const char *); int (*bgets) (BIO *, char *, int); long (*ctrl) (BIO *, int, long, void *); int (*create) (BIO *); int (*destroy) (BIO *); long (*callback_ctrl) (BIO *, int, bio_info_cb *); };
typedef struct { char *fpos; void *base; unsigned short handle; short flags; short unget; unsigned long alloc; unsigned short buffincrement; } FILE;
BIO *BIO_new(BIO_METHOD *type);
BIO *BIO_new_fp(FILE *stream, int close_flag);
BIO *BIO_push(BIO *b, BIO *append);
int BIO_write(BIO *b, const void *data, int dlen);
int BIO_read(BIO *b, void *buf, int len);
int BIO_flush(BIO *b);
void BIO_free_all(BIO *a);
BIO_METHOD *BIO_f_base64(void);
FILE *fopen(const char *filename, const char *mode);
int fprintf(FILE *stream, const char *format, ...);
int fclose(FILE *stream);
]]
BIO_NOCLOSE = 0 --# define BIO_NOCLOSE 0x00
BIO_CLOSE = 1 --# define BIO_CLOSE 0x01
ssl = ffi.load('/usr/lib/libssl.so')
f = ffi.C.fopen("/tmp/test", "a+")
bio = ffi.new('BIO')
b64 = ffi.new('BIO')
str = "Hello World"
b64 = ssl.BIO_new(ssl.BIO_f_base64())
bio = ssl.BIO_new_fp(f, BIO_NOCLOSE)
ssl.BIO_push(b64, bio)
=ssl.BIO_write(b64, str, #str) --This yields 11 in the Lua interpreter. This function returns an int with the number of bytes successfully written so apparently the string was written to the file.
ssl.BIO_flush(b64)
ssl.BIO_free_all(b64)
ffi.C.fclose(f)
What's wrong with this header? Gcc throws out:
libmmbox.h:7:29: error: expected ‘)’ before ‘*’ token
libmmbox.h:8:27: error: expected ‘)’ before ‘*’ token
Here's my code:
#ifndef __LIBMMBOX_H__
#define __LIBMMBOX_H__
int mmbox_connect(char *username);
int mmbox_login(int token, char *password);
int mmbox_quit();
int mmbox_stat(mmbox_stat_t *result);
int mmbox_list(mmbox_mail **l, int *num_msg);
int mmbox_send(char *dest, char *obj, void *buf, size_t size);
int mmbox_rcv(int id, void *buf, size_t size);
int mmbox_delete(int id);
int mmbox_resume(int id);
typedef struct
{
char *user;
int used_space;
int free_space;
int num_msg;
} mmbox_stat_t;
typedef struct
{
char *sender, *recipient; /
char *obj, *date;
char flags;
size_t size;
} mmbox_mail;
#endif
mmbox_stat_t struct is declared after it is used into a function signature. So the compiler doesn't still know this type when you declare:
int mmbox_stat(mmbox_stat_t *result);
Put your function prototypes after data structures definition.