Peek file content
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#define KO_BUFSIZE 0x40000
typedef struct {
FILE *fp_in, *fp_out;
int bufsize, is_closed;
uint8_t *buf;
uint64_t offset;
pthread_t tid;
} kofile_t;
static void *worker(void *data)
{
kofile_t *f = (kofile_t*)data;
do {
if (fwrite(f->buf, 1, f->bufsize, f->fp_out) != f->bufsize) break;
f->offset += f->bufsize;
f->bufsize = fread(f->buf, 1, KO_BUFSIZE, f->fp_in);
} while (f->bufsize > 0);
fclose(f->fp_in);
fclose(f->fp_out);
f->is_closed = 1;
pthread_exit(0);
}
const uint8_t *ksf_peek(void *data, int *size, uint64_t *offset)
{
kofile_t *f = (kofile_t*)data;
*size = f->bufsize;
*offset = f->offset;
return f->buf;
}
void *ksf_open(const char *fn, int *_fd)
{
int fd[2];
kofile_t *fp;
*_fd = -1;
if (pipe(fd) < 0) return 0;
if ((fp = (kofile_t*)calloc(1, sizeof(kofile_t))) == 0) return 0;
if ((fp->fp_in = fn? fopen(fn, "rb") : stdin) == 0) {
free(fp);
return 0;
}
fp->fp_out = fdopen(fd[1], "wb");
fp->buf = (uint8_t*)calloc(KO_BUFSIZE, 1);
fp->bufsize = fread(fp->buf, 1, KO_BUFSIZE, fp->fp_in);
pthread_create(&fp->tid, 0, worker, fp);
*_fd = fd[0];
return (void*)fp;
}
int ksf_close(void *data)
{
kofile_t *f = (kofile_t*)data;
if (f == 0) return -1;
pthread_kill(f->tid, 13); // send SIGPIPE
pthread_join(f->tid, 0);
if (!f->is_closed) {
fclose(f->fp_in);
fclose(f->fp_out);
}
free(f->buf);
return 0;
}
#ifdef MAIN_KSFILE
int main(int argc, char *argv[])
{
void *fp;
int fd, size;
uint64_t offset;
const uint8_t *buf;
FILE *f;
uint8_t b[0x10000];
fp = ksf_open(argv[1], &fd);
buf = ksf_peek(fp, &size, &offset);
fprintf(stderr, "First two bytes: %.2X %.2X; size: %d; offset: %lu; fd: %d\n", buf[0], buf[1], size, (long)offset, fd);
f = fdopen(fd, "rb");
while (fread(b, 1, 0x10000, f) > 0);
ksf_close(fp);
return 0;
}
#endif