Writing Archives
This guide explains how to construct TAR archives, configure file metadata, write data payloads, and finalize standard-compliant archives using minipaxtar.
Creating an Archive
Creating a TAR archive involves a structured four-step lifecycle for every file entry:
- Initialize Writer: Pass your write callback, stream handle, and memory allocators to
mptar_writer. - Write Header: Populate
mptar_metadatawith your data and usemptar_write_header()to write it to the stream. You don't need to worry about the path sizes,minipaxtarwill automatically use extensions if the path doesn't fit. - Stream Payload: Write data blocks using
mptar_write_data_chunk(). - Finalize & Close: Call
mptar_write_finalize()to pad the current file entry to a 512-byte boundary, then callmptar_close_archive()to append the trailing EOF blocks.And finally use
mptar_close_archive(&writer)after all entries are written to close the archive.
Example
This example below is fully copyable! Just copy it and test it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "minipaxtar.h"
static mptar_size_t stdlib_tar_write(void *u, const void *b, mptar_size_t s)
{ return (mptar_size_t)fwrite(b, 1, s, (FILE*)u); }
static void* stdlib_tar_alloc(void *u, mptar_size_t s) { (void)u; return malloc(s); }
static void stdlib_tar_free(void *u, void *p) { (void)u; free(p); }
void create_archive_example(const char *output_path) {
FILE *file_out = fopen(output_path, "wb");
if (!file_out) return;
mptar_writer writer = {
.write = stdlib_tar_write,
.write_user_data = file_out,
.memory = {
.alloc = stdlib_tar_alloc,
.free = stdlib_tar_free,
.alloc_user_data = NULL
}
};
/* 1. Define file payload and metadata */
const char *payload = "Hello, minipaxtar!";
mptar_size_t payload_len = (mptar_size_t)strlen(payload);
mptar_metadata meta = {0};
meta.path = "hello.txt";
meta.size = payload_len;
meta.mode = 0644;
meta.typeflag = '0'; /* Regular file */
/* Optional timestamp setup */
meta.mtime.has_value = true;
meta.mtime.value.sec = 1700000000;
meta.mtime.value.nsec = 0;
/* 2. Write Header */
int status = mptar_write_header(&writer, &meta);
if (status != MPTAR_OK) {
fprintf(stderr, "Failed to write header: %d\n", status);
fclose(file_out);
return;
}
/* 3. Write Data Chunk */
int err = MPTAR_OK;
mptar_write_data_chunk(&writer, payload, payload_len, &err);
/* 4. Finalize Stream Entry (Pads entry payload to 512-byte alignment) */
mptar_write_finalize(&writer, &meta);
/* 5 (final). Close Archive (Writes two 512-byte blocks of null bytes at EOF) */
mptar_close_archive(&writer);
fclose(file_out);
}
int main(int argc, char const *argv[])
{
create_archive_example("new_archive.tar");
return 0;
}
Writing Mechanics & Lifecycle
| Stage | Function | Description |
|---|---|---|
| Header Write | mptar_write_header() |
Converts metadata fields into a standard USTAR block (or generates a PAX extended header block if paths/timestamps exceed standard formats). |
| Data Chunks | mptar_write_data_chunk() |
Streams raw file content to your write callback. Can be called repeatedly for large files. |
| Entry Alignment | mptar_write_finalize() |
Calculates remaining unaligned bytes for the current file and writes null padding to round the entry out to a multiple of 512 bytes. |
| Archive Termination | mptar_close_archive() |
Appends two 512-byte blocks of zero bytes (0x00) to signal end-of-archive (EOA) per POSIX TAR specifications. |
Important: Always call
mptar_close_archive(&writer)before closing your underlying file handle to ensure that the generated archive conforms to standard TAR tools liketaror7z.
Write chunks in loops
Often payloads need to be written in chunks, especially if you're constained in memory. Because mptar_write_data_chunk() can be used to write smaller buffers of data, what you can do is implement a loop which:
- Reads data from your source into a buffer,
- Pass the buffer to the
mptar_write_data_chunk()to write it, - Check for errors and continue until
mptar_write_data_chunkreturns 0 with no errors.
You should not ignore errors from
mptar_write_data_chunk(). It will return 0 in case of an error because the returning type of it is unsigned (mptar_size_t).
Check how you can read archives too