I'm trying to call some ioctls from Go, and some of them take C strings as parameters. For example, in C:
/* When the user asks to bind a message name to an interface, they use: */
struct kbus_bind_request {
__u32 is_replier; /* are we a replier? */
__u32 name_len;
char *name;
};
extern int kbus_ksock_bind(kbus_ksock_t ksock,
const char *name,
uint32_t is_replier)
{
int rv;
kbus_bind_request_t bind_request;
bind_request.name = (char *) name;
bind_request.name_len = strlen(name);
bind_request.is_replier = is_replier;
rv = ioctl(ksock, KBUS_IOC_BIND, &bind_request);
if (rv < 0)
return -errno;
else
return rv;
}
I converted the struct to a Go struc like this:
type kbus_bind_request struct {
is_replier uint32 /* are we a replier? */
name_len uint32
name unsafe.Pointer // char*
}
Now, how do I convert a Go string to a C string stored in an unsafe.Pointer? I don't want to use CGo as I am cross-compiling and it makes things a pain.
Ah found the answer (well something that compiles anyway). First cast to []byte, then take the address of the first element:
func int_bind(ksock int, name string, is_replier uint32) int {
bind_request := &kbus_bind_request{}
s := []byte(name)
bind_request.name = unsafe.Pointer(&s[0])
bind_request.name_len = uint32(len(s))
bind_request.is_replier = is_replier
rv := ioctl(ksock, KBUS_IOC_BIND, unsafe.Pointer(bind_request))
if rv != 0 {
return -int(rv)
}
return 0
}
Related
In linux kernel if we have a pointer to "struct gendisk" of a disk, then how can we read a known sector number from the disk.
These functions helped me. I used submit_bio and submitted a bio to the disk. The major and minor shall be assumed as input to read_sector_thread_func
static struct bio * my_mpage_alloc(struct block_device *bdev,
sector_t first_sector, int nr_vecs,
gfp_t gfp_flags)
{
struct bio *bio;
bio = my_bio_alloc(gfp_flags, nr_vecs);
if (bio == NULL && (current->flags & PF_MEMALLOC)) {
while (!bio && (nr_vecs /= 2))
bio = my_bio_alloc(gfp_flags, nr_vecs);
}
if (bio) {
//bio->bi_bdev = bdev;
bio->bi_iter.bi_sector = first_sector;
}
return bio;
}
static void src_endio(struct bio *bio)
{
if (bio->bi_private) {
complete(bio->bi_private);
}
return;
}
static int read_sector_thread_func(void *data)
{
struct block_device *r_bdev = NULL;
struct bio *r_bio = NULL;
struct page *page = NULL;
int part = NULL;
int len = 0;
struct gendisk * disk = NULL;
unsigned char * addr;
u64 first_sector_num = 0;
disk = get_gendisk(MKDEV(global_dev_major, global_dev_minor), &part);
DECLARE_COMPLETION_ONSTACK(r_wait);
page = alloc_pages(GFP_ATOMIC, 0);
printk("%d : %s ", __LINE__, __func__);
r_bio = my_mpage_alloc(r_bdev, first_sector_num, 1, GFP_ATOMIC);
if(r_bio==NULL)
{
printk("bio is NULL");
return;
}
bio_add_page(r_bio, page, 512, 0);
r_bio->bi_private = &r_wait;
r_bio->bi_end_io = src_endio;
r_bio->bi_disk = disk;
bio_associate_blkg(r_bio);
bio_get(r_bio);
bio_set_op_attrs(r_bio, REQ_OP_READ, 0);
submit_bio(r_bio);
wait_for_completion_io(&r_wait);
bio_put(r_bio);
return 0;
}
I have the following protocol buffer (proto3 syntax)
message Operation {
enum Operator {
UNKNOWN = 0;
ADD = 1;
...
}
float operand = 1;
Operator operator = 2;
}
The enum is generated as
type Operation_Operator int32
I'm creating the Operation message like so
//Assume package is pb
oper, found := pb.Operation_Operator_value(os.Args[1]) // one of the enums
if !found {
// do something
}
msg := &pb.Operation {
Operand: float32(aNum),
Operator: pb.Operation_Operator(oper),
}
My question is is there an idiomatic way of converting int32 to Operation_Operator apart from casting as I did above?
I am not able to allocate memory for nested structures using pointers.
What syntax should I use to allocate the memory for lots of structures that have pointers to other structures? How should I go about accessing the values in the structures once the memory is allocated?
struct A {
int *a;
struct B *b;
};
struct B {
int *b;
struct C *c;
};
struct C {
int *c;
struct D *d;
};
struct D {
int *d;
};
int main(int argc, const char* argv[]) {
struct A* foo;
/* Structure allocation */
/* use of structures */
}
I can't go beyond 2 nested structures. Beyond that I start getting Segmentation fault.
I tried something like this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct file f1;
typedef struct command c1;
typedef struct arguments a1;
typedef struct ccity ccity;
typedef struct csub csub;
struct arguments {
char *argname;
struct arguments *next;
};
struct command {
char *cmdname;
struct arguments *args;
};
struct file{
int fileid;
char *filename;
struct command *cmd;
};
struct sub{
char *subname;
};
struct city {
char *city_name;
struct sub *s11;
};
struct road{
char *name;
struct city *next_city;
};
int main()
{
char name[] = "HELLO ";
struct file *f1;
struct city *c1 = NULL;
struct road *r1 = NULL;
struct sub *s1 = NULL;
printf("HELOOOOOOOOO");
f1->filename;
f1 = malloc(10*sizeof(struct file ));
f1->filename = (char *)malloc(10*sizeof(char *));
c1 = malloc(sizeof(c1));
r1 = malloc(sizeof(r1));
s1 = malloc(sizeof(s1));
r1->name = malloc(100*sizeof(char *));
r1->next_city = malloc(100*sizeof(r1->next_city));
c1->city_name = malloc(100*sizeof(char *));
c1->s11 = malloc(100*sizeof(c1->s11));
c1->s11->subname = calloc(120,sizeof(char*));
(*c1).s11->subname = "text";
(*r1).next_city->s11->subname =
malloc(10 * sizeof((*r1).next_city->s11->subname));
strncpy((*r1).next_city->s11->subname,"sant",4);
r1->name = malloc(sizeof(char *));
c1->city_name = malloc(sizeof(char *));
r1->next_city = malloc(sizeof(char *));
r1->next_city->city_name = "Hello";
/*strcpy(f1->filename,"file1");
printf("name is %s\n",(f1->filename));
c1->cmdname = (char *)malloc(10*sizeof(c1->cmdname));
strcpy(f1[0].cmd[0].cmdname,"command1");
printf("name is %s\n",f1[0].cmd[0].cmdname);
strcpy(f1[0].cmd[1].cmdname,"command2");
printf("name is %s\n",f1[0].cmd[1].cmdname);
strcpy(f1[0].cmd[2].cmdname,"command3");
printf("name is %s\n",f1[0].cmd[2].cmdname);
strcpy(f1[0].cmd[2].args[0].argname,"argument1");
printf("name is %s\n",f1[0].cmd[2].args[0].argname);
strcpy(f1[0].cmd[2].args[0].argname,"argument1");
printf("name is %s\n",f1[0].cmd[2].args[1].argname);
(f1[0].cmd[0].args[0]).argname = malloc(20*sizeof(char*));
strcpy((f1[0].cmd[0].args[0]).argname,"argument1");
printf("name is %s\n",(f1[0].cmd[0].args[0]).argname);
*/
}
I'm going through a source code analyzing its implementations where I have a method defined :
unsigned int rs_calc_weak_sum(void const *p, int len) {
unsigned char const *buf = (unsigned char const *) p;
}
What type of parameter should be passed into this method??
please help me.
thanks.
Any pointer can be passed to a void * parameter. What 'should' be passed, depends on what the code does with that parameter.
char array[12] = "Hello World";
unsigned in res = 0;
res = rs_calc_weak_sum(array, 12);
#include <stdio.h>
int main ( void )
{
char filename[] = "file.txt";
FILE *file = fopen ( filename, "r" );
if (file != NULL) {
char line [1000];
while(fgets(line,sizeof line,file)!= NULL) /* read a line from a file */ {
res = rs_calc_weak_sum(line, 1000);
}
fclose(file);
}
else {
perror(filename); //print the error message on stderr.
}
return 0;
}
I have a memory location a and I want to copy a certain amount of bytes to another location fast, how would I do this in D ?
For example how would i do this:
int main()
{
void* src_data = 0x40001255;
void* dst_data = 0x47F22000;
u32 size = 0x200;
memcpy(dst_data, src_data, size);
}
Also how would fill a struct fast:
struct data_struct
{
u32 block1;
u32 block2;
u32 block3;
u32 block4;
u32 block5;
u62 block6;
u128 bigblock;
} data_struct_t;
int main()
{
void* src_data = 0x40001255;
struct data_struct_t dst_data;
u32 size = sizeof(data_struct);
memcpy(dst_data, src_data, size);
}
Thanks!
Roel
Assigning to a slice will perform an array copy, which calls memcpy internally.
void main()
{
void* src_data = 0x40001255;
void* dst_data = 0x47F22000;
uint size = 0x200;
dst_data[0..size] = src_data[0..size];
}
For the second one:
struct data_struct
{
uint block1, block2, block3, block4, block5;
ulong block6;
uint[4] bigblock;
}
void main()
{
auto src_data = cast(data_struct*) 0x40001255; // unaligned, WTF?!
auto dst_data = *src_data;
}
Note that you also have access to C's memcpy in D. D can directly access C's whole standard library.