#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE (1<<17)
typedef struct args { int rval; int blockSize; int fnum; int *files; } args_t;
args_t parseArgs(int argc, char **argv);
int main(int argc, char **argv) {
args_t a = parseArgs(argc, argv);
if (a.rval < 0) { return a.rval; }
int outputBufsize = BUFSIZE * a.fnum;
char ibuf[BUFSIZE];
char *obuf = malloc(outputBufsize * sizeof(char));
char reachedEOF = 0;
while (!reachedEOF) {
int readBytes = outputBufsize;
for (int i = 0; i < a.fnum; i++) {
ssize_t r = read(a.files[i], ibuf, BUFSIZE);
for (int bi = 0; bi < r; bi++) {
obuf[a.fnum * bi + i] = ibuf[bi];
}
if (r < BUFSIZE) {
if (readBytes > a.fnum * r + i) {
readBytes = a.fnum * r + i;
}
}
if (r == 0) {
reachedEOF = 1;
}
}
ssize_t w = write(STDOUT_FILENO, obuf, readBytes);
}
// Discharging allocations.
for (int i = 0; i < a.fnum; i++) { close(a.files[i]); }
free(a.files); free(obuf);
return 0;
}
args_t parseArgs(int argc, char **argv) {
args_t a;
a.rval = 0;
a.blockSize = 1;
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
fprintf(stderr, "Usage: intertwine [args] <FILE1> <FILE2>\n");
fprintf(stderr, "Intertwine blocks from two sources.\n");
fprintf(stderr, "\n");
fprintf(stderr, " --block-size: as bytes (default 1).\n");
a.rval = -1;
continue;
} else if (strcmp(argv[i], "--block-size") == 0) {
a.blockSize = atoll(argv[++i]);
continue;
} else if (strcmp(argv[i], "--") == 0) {
i++;
break;
} else if (argv[i][0] != '-') {
break;
}
}
// Read the files.
a.fnum = argc - i;
a.files = malloc(a.fnum * sizeof(int));
for (int j = i; j < argc; j++) {
a.files[j - i] = open(argv[j], O_RDONLY);
}
return a;
}