LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-01-2012, 09:52 AM   #1
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Colombia
Distribution: Kubuntu, Debian, Knoppix
Posts: 1,982
Blog Entries: 1

Rep: Reputation: 83
libtar: what is the right way to use libtar with buffers instead of files?


Hi!

I want to handle tgz files that are in memory. At the time I'm working with a tar file that I have read into memory. I create a FILE * with fmemopen, I can read the file content with fgetc successfully on the FILE * created by fmemopen. Now, when I try to use this file with libtar, I get a Bad file descriptor message on th_read() (though tar_fdopen was successful).

Code:
FILE* memoryFile = fmemopen(fileContent, fileSize + 1, "rb");
.
.
.
TAR *t;
if(tar_fdopen(&t, fileno(memoryFile), NULL, O_RDONLY, 0, TAR_VERBOSE, TAR_GNU) == 0) {
        fprintf(stderr, "File successfully opened by tar\n");
} else {
        fprintf(stderr, "Couldn't open tgz file\n");
        fprintf(stderr, "tar_open(): %s\n", strerror(errno));
        return 1;
}

while ((i = th_read(t)) == 0) {
        th_print_long_ls(t);

        if (TH_ISREG(t) && tar_skip_regfile(t) != 0) {
                fprintf(stderr, "tar_skip_regfile(): %s\n",
                        strerror(errno));
                return -1;
        }
}

if (i == 1) {
        fprintf(stderr, "Reached EOF\n");
} else if (i == -1) {
        fprintf(stderr, "th_read(): %s\n", strerror(errno));
        return -1;
}
Is there a problem with fileno() or it's just not possible to use libtar from buffers at all?
 
Old 08-01-2012, 10:05 AM   #2
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Colombia
Distribution: Kubuntu, Debian, Knoppix
Posts: 1,982
Blog Entries: 1

Original Poster
Rep: Reputation: 83
Oh, I get it. The problem is that fileno returns -1 which means it's a bad file descriptor.... also from fmemopen's man page:

Code:
There is no file descriptor associated with the file stream returned by these functions (i.e., fileno(3) will return an error if called on the returned stream).
And that ends my adventure into using fmemopen and then tar_fdopen. What's the right way to do it then? Thanks in advance.
 
Old 08-01-2012, 10:41 AM   #3
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Colombia
Distribution: Kubuntu, Debian, Knoppix
Posts: 1,982
Blog Entries: 1

Original Poster
Rep: Reputation: 83
Got it. Have to set a custom tartype_t when calling tar_fdopen that calls your own handlers for opening/reading/writing/closing.
 
Old 08-01-2012, 05:02 PM   #4
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Colombia
Distribution: Kubuntu, Debian, Knoppix
Posts: 1,982
Blog Entries: 1

Original Poster
Rep: Reputation: 83
I'm having a lot of fun over here.

I can correctly use my custom function to read the tar file except when I try to get the content of the files with tar_block_read. When I only use th_read/tar_skip_regfile it works like a charm. I can get the filename, the file size of all files, print them to stderr, beautyful!.

Now, when I try to run tar_block_read, I get to read the content of the first file (this as a matter of fact is a proxy call to my custom reader) and then libtar goes nuts and can't seem to see the other files. From libtar.h:

Code:
#define tar_block_read(t, buf) (*((t)->type->readfunc))((t)->fd, (char *)(buf), T_BLOCKSIZE)
The only thing is that T_BLOCKSIZE is some value that is not related to the size of the file I want to read (and in my custom reader I don't have any check for file (as in files in the tar) boundaries.... you ask me to read 512 bytes? I'll read 512 bytes). This sounds a little weird because seems like libtar is asking to read the same mount of bytes per secula seculorum. I'd expect to get a call controlled by libtar adjusting to what's left of the file I want to expand.

So, what I did is replace the call for tar_block_read for a call to t->type->readfunc (in other words, an indirect call to my custom reader) with the actual size of the file I want to extract. That works and I get the contents of the file, however, I think that given that I moved the position of the pointer in the tar file, now calls to th_read fail (it's like something else has to be called after tar_block_read so that libtar gets the pointer at the right location or something like that). Can anybody give me a hand over here?

Thanks in advance.

Last edited by eantoranz; 08-01-2012 at 05:04 PM.
 
Old 08-01-2012, 05:19 PM   #5
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Colombia
Distribution: Kubuntu, Debian, Knoppix
Posts: 1,982
Blog Entries: 1

Original Poster
Rep: Reputation: 83
This is a utterly simple (and un-elegant) hack but it works.

Given that libtar is calling my own writer to get the file content, I created another writer (not related to libtar) that can read from memory _without_ moving the memory pointer for libtar... in other words, libtar leaves the pointer where I need it with th_read and then I read memory (behind libtar's back) to get file content and then I can call tar_skip_regfile() to get to the next file's position. How about that?

But there has to be a clean way to do it, don't you think? What's that?
 
  


Reply

Tags
bad file descriptor, error, fileno, fmemopen, libtar


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with libtar api and large files SirSeoman Programming 1 01-04-2009 07:14 AM
Flash buffers alaios Linux - General 2 04-29-2006 10:18 AM
[C++] buffers streams Ossar Programming 1 06-14-2005 12:27 PM
About buffers? eshwar_ind Programming 2 04-30-2004 05:13 AM
eth1: no RX buffers subhasis_ray Linux - Networking 1 11-11-2002 06:45 AM


All times are GMT -5. The time now is 10:56 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration