How do I read response headers from a response using libCurl in C?
The MAN page says this:
size_t function( void *ptr, size_t size, size_t nmemb, void *stream)
What is the stream here? Do I read headers from stream or from ptr?
I am currently trying to read code from ptr and passing a struct for stream.
And the only response header is see is http/1. 0 ok. Nothing else and I am pretty sure the response has more headers
The last parameter isn't a stream, it's a void* to your userdata if used. The data to read is in *ptr, and this function will be called once for each header received.
(The last parameter is often used to point back to an C++ object instance through a static method using the C-style API...)
One example here:
http://permalink.gmane.org/gmane.comp.web.curl.library/28803
Related
So I am working on a project and I am failing to put all the pieces together to make this work. We need to read in the header of a binary file and store them at the specified pointer.
the function I am working in:
int read_header (FILE *file, elf_hdr_t *hdr);
I understand how to pass the info to the function but I am failing to understand how to read in to the specified pointer. I have been trying to find information on this all day but cant really figure out my starting point... Thanks for any direction you can provide.
My code so far:
int read_header (FILE *file, elf_hdr_t *hdr)
{
int read;
read = fread(hdr, 1, sizeof(hdr), file);
fclose(file);
}
I want to know if I am doing what I am trying here, basically want to read in one byte at a time to the specified pointer.
Since hdr is a pointer, sizeof(hdr) will just be the size of a pointer. You want sizeof(*hdr) or sizeof(elf_hdr_t) to get the size of the elf header struct that the pointer points at...
please re-read the MAN page for fread()
These two parameters: 1, sizeof(hdr), are saying to read in sizeof(hdr) bytes, not to read in 1 byte
I'm trying to send an encrypted message in a simple server-client chat program.
This is the send() call:
int send(int sockfd, const void *msg, int len, int flags);
Can I pass an int array as *msg?
I think you can use the send() system call. But be aware, that the len is the length of the message in bytes. So i think for an array of 5 int. You need to specify the len as 5*(sizeof(int)).
Additionally, on the receiving side, you need to interpret it accordingly.
As Naveen pointed out, a more detailed answer to your question is already present here.
Yes, you are allowed to pass an array of ints to send(). The reason you're allowed to do that is arrays are automatically converted to pointers when they are passed to functions. See this previous question.
In addition, any pointer in C is can be automatically cast to void * if necessary. Void pointers were designed to provide implicit conversion.
I'm designing a system where I read from a SD card and send the information via Bluetooth.
To do that, firstly I ready data from a SD card and store the bytes in an array byte of a fixed length:
char final_name[17];
And to send it via Bluetooth, I defined the Bluetooth as a stream, and I'm calling printf to send data:
fprintf(BLUETOOTH, final_name);
The problem here:
This function was designed to work with:
int fprintf(FILE *stream, const char *format, …);
so this works perfect and only 8 bytes are sent:
fprintf(BLUETOOTH, "name.txt");
But I need to send a variable size byte array. I was looking for similar functions to fprintf but where you can expecified the lenght of bytes you want to print, but I couldn't find.
Does anyone knows witha format simiar to:
int fprintf(FILE *stream, char *format, int lenght);
You can use fwrite for writing an arbitrary data with a given length into a file (or device file), not only strings.
In following functions, taken from LDD:
ssize_t read(struct file *filp, char __user *buff, size_t count, loff_t *offp);
ssize_t write(struct file *filp, const char __user *buff, size_t count, loff_t *offp);
Why there is the need of loff_t *offp? Can't I use directly filp to update f_pos?
Moreover in page 54 the author says:
Read and write should update a position using the pointer they receive as the last argument instead of acting on filp->f_pos directly. The one exception to this...
OK, so it's better to use the offp pointer, but why?
filp->f_pos is current pointer position in file, whereas offp is where user does access to file. You advance file pointer on successful read/write operation, if you failed you should not change file pointer. Kernel does it itself, if you successfully did read/write it will change filp->f_pos to offp. Citing LDD3:
Whatever the amount of data the methods transfer, they should
generally update the file position at *offp to represent the current
file position after successful completion of the system call. The
kernel then propagates the file position change back into the file
structure when appropriate.
One reason could be to support the pread, pwrite, preadv, pwritev syscalls, which take an offset as one of the arguments, and are specified to NOT update the file position. It seems cleaner to have the lower layer code implement something close to the p* functions, and then have wrappers that use filp->f_pos and update the position for the plain read/write/readv/writev syscalls.
gcc 4.7.2
c89
bstrlib.h from Better String Library
I am maintaining someone's code that looks like this:
FILE *db_fp = NULL;
bstring data = NULL;
db_fp = db_open(DB_FILE, "r");
LOG_CHECK(db_fp == NULL, "Failed to open database: %s", DB_FILE);
data = bread((bNread)fread, db_fp);
LOG_CHECK(data == NULL, "Failed to read from db file: %s", DB_FILE);
db_close(db_fp);
return data;
I am having a little trouble understanding the following line:
data = bread((bNread)fread, db_fp);
What I can guess, is that it is fetching a bstream from the following file pointer and returning a bstring. However, I am wondering about bread and fread.
bread contains 2 arguments, A function pointer (bNread) and the file pointer. But I am not sure I understand how it works.
The declaration for bread() in the Better String Library documentation is:
typedef size_t (*bNread)(void *buff, size_t elsize, size_t nelem, void *parm);
extern bstring bread(bNread readPtr, void *parm);
Therefore, bread() is a function that takes a pointer to a function as an argument. The bNread type is used to specify the type of function. The fread() function is close enough to pass muster when cast — the match isn't exact because it expects a FILE * for its fourth argument and a true function of the type pointed at by a bNread expects a void *. The second argument to bread is the value to be passed as the fourth argument to the function pointed to by the bNread.
So, in the code you're maintaining:
data = bread((bNread)fread, db_fp);
The Better String Library function is called with fread() as the I/O function, cast to the correct type to quell an otherwise justified compiler warning about a mismatch in types, plus the file stream that should be used for reading.
The implementation of the bread() function uses the function pointer and the stream pointer whenever it needs to do I/O in order to read a string. That is, as KerrekB also explained, the code
might write something like:
char buffer[256];
size_t nbytes = (*readPtr)(buffer, sizeof(char), sizeof(buffer), parm);
or (equivalently):
size_t nbytes = readPtr(buffer, sizeof(char), sizeof(buffer), parm);
(If you learned C long enough ago, the first was the only way to invoke functions through pointers to functions; since the C89 standard was produced, the second has been available and is probably used more widely these days.) There are a number of tricks that the implementation must worry about, but the basic function call would be somewhat similar. The code could use I/O functions other than fread(), though the interface to the function must be similar.
Pointers to functions are powerful, but are arcane until you've used them.
Here's one possible implementation of bread:
bstring bread(int(*func)(void *, size_t, size_t ,FILE *), FILE * fp)
{
char buf[10];
bstring result;
func(buf, 10, 1, fp);
return result;
}
This doesn't of course reflect what the real function bread is doing, but it should give you an idea how an implementation might use it.
(The real function would of course read a length from fp first, then allocate enough memory for the string, and then read the string, but the details depend on what bstring is and how it works. A real implementation would also check the return value of func!)