Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to create dummy file descriptor in linux?

Tags:

c

file

linux

I have opened one file with following way:

fp = fopen("some.txt","r");

Now in this file the 1st some bytes lets say 40 bytes are unnecessary junk of data so I want to remove them. But I cannot delete that data from that file, modify or create duplicates of that file without that unnecessary data.

So I want to create another dummy FILE pointer which points to the file and when I pass this dummy pointer to any another function that does the following operation:

  fseek ( dummy file pointer , 0 , SEEK_SET );

then it should set the file pointer at 40th position in my some.txt.


But the function accepts a file descriptor so i need to pass a file descriptor which will treat the file as those first 40 bytes were never in the file.


In short that dummy descriptor should treat the file as those 40 bytes were not in that file and all positioning operations should be with respect to that 40th byte counting as the is 1st byte.

like image 994
Jeegar Patel Avatar asked Jun 15 '12 04:06

Jeegar Patel


4 Answers

Easy.

#define CHAR_8_BIT    (0)
#define CHAR_16_BIT   (1)
#define BIT_WIDTH     (CHAR_8_BIT)

#define OFFSET        (40)

FILE* fp = fopen("some.txt","r");
FILE* dummy = NULL;

#if (BIT_WIDTH == CHAR_8_BIT)
dummy = fseek (fp, OFFSET*sizeof(char), SEEK_SET);
#else
dummy = fseek (fp, OFFSET*sizeof(wchar_t), SEEK_SET);
#endif

The SEEK_SET macro indicates beginning of file, and depending on whether you are using 8-bit characters (ASCI) or 16-bit characters (eg: UNICODE) you will step 40 CHARACTERS forward from the beginning of your file pointer, and assign that pointer/address to dummy.

Good luck!

These links will likely be helpful as well:

char vs wchar_t

http://www.cplusplus.com/reference/clibrary/cstdio/fseek/

If you want, you can just convert a file descriptor to a file pointer via the fdopen() call.

http://linux.die.net/man/3/fdopen

like image 168
Cloud Avatar answered Sep 21 '22 20:09

Cloud


fseek ( dummy file pointer , 0 , SEEK_SET );

In short that dummy pointer should treat the file as there is no that 40 byte in that file and all position should be with respect to that 40th byte as counting as it is 1st byte.

You have conflicting requirements, you cannot do this with the C API.

SEEK_SET always refers to the absolute position in the file, which means if you want that command to work, you have to modify the file and remove the junk.

On linux you could write a FUSE driver that would present the file like it was starting from the 40th byte, but that's a lot of work. I'm only mentioned this because it's possible to solve the problem you've created, but it would be quite silly to actually do this.

The simplest thing of course would be just to abandon this emulating layer idea you're looking for, and write code that can handle that extra header junk.

like image 38
Karoly Horvath Avatar answered Sep 21 '22 20:09

Karoly Horvath


If you want to remove the first 40 bytes of a file on the disk without creating another file, then you can copy the content from the 41th byte and onwards into a buffer, then write it back at offset -40. Then use ftruncate (a POSIX library in unistd.h) to truncate at (filesize - 40) offset.

like image 2
nhahtdh Avatar answered Sep 23 '22 20:09

nhahtdh


I wrote a small code with what i understood from your question.

#include<stdio.h>

void readIt(FILE *afp)
{
    char mystr[100];
    while ( fgets (mystr , 100 , afp) != NULL )
       puts (mystr);
}
int main()
{
    FILE * dfp = NULL;
    FILE * fp = fopen("h4.sql","r");
    if(fp != NULL)
    {
        fseek(fp,10,SEEK_SET);
        dfp = fp;
        readIt(dfp);
        fclose(fp);
    }
}

The readIt() is reading the file from the 11 byte. Is this what you are expecting or something else?

like image 1
Raghuram Avatar answered Sep 24 '22 20:09

Raghuram