88 lines
2.1 KiB
C
88 lines
2.1 KiB
C
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
#include <time.h>
|
|
|
|
volatile sig_atomic_t shutdown_flag = 0;
|
|
volatile sig_atomic_t stats_flag = 0;
|
|
|
|
void handle_sigint(int sig) {
|
|
shutdown_flag = 1;
|
|
}
|
|
|
|
void handle_sigusr1(int sig) {
|
|
stats_flag = 1;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
struct sigaction sa_sigint;
|
|
sa_sigint.sa_handler = handle_sigint;
|
|
sigemptyset(&sa_sigint.sa_mask);
|
|
sa_sigint.sa_flags = 0;
|
|
sigaction(SIGINT, &sa_sigint, NULL);
|
|
|
|
struct sigaction sa_sigusr1;
|
|
sa_sigusr1.sa_handler = handle_sigusr1;
|
|
sigemptyset(&sa_sigusr1.sa_mask);
|
|
sa_sigusr1.sa_flags = 0;
|
|
sigaction(SIGUSR1, &sa_sigusr1, NULL);
|
|
|
|
int max_lines = -1; // -1 means unlimited
|
|
int verbose = 0;
|
|
|
|
// Parse arguments (-n max_lines, -v verbose)
|
|
char opt;
|
|
while ((opt = getopt(argc, argv, "n:v")) != -1) {
|
|
switch (opt) {
|
|
case 'n':
|
|
max_lines = atoi(optarg); break;
|
|
case 'v':
|
|
verbose = 1; break;
|
|
default:
|
|
printf("Usage: %s [-n max_lines] [-v]\n", argv[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
clock_t start = clock();
|
|
|
|
// Read from stdin line by line
|
|
// Count lines and characters
|
|
// If verbose, echo lines to stdout
|
|
char buffer[256];
|
|
int lines = 0;
|
|
int chars = 0;
|
|
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
|
|
int size = strlen(buffer);
|
|
if (verbose)
|
|
fwrite(buffer, sizeof(char), size, stdout);
|
|
chars += size;
|
|
if (size > 0 && buffer[size - 1] == '\n')
|
|
lines++;
|
|
if (lines == max_lines)
|
|
break;
|
|
|
|
// Handle shutdown
|
|
if (shutdown_flag) {
|
|
fprintf(stderr, "Cancelled\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// Print statistics to stderr (handle SIGUSR1)
|
|
if (stats_flag) {
|
|
clock_t end = clock();
|
|
double time = ((double)(end - start)) / CLOCKS_PER_SEC;
|
|
double throughput = (double)chars / 1024.0 / 1024.0 / time;
|
|
printf("Stats:\n");
|
|
printf("File Size: %d bytes\n", chars);
|
|
printf("Total Time: %.3f secs\n", time);
|
|
printf("Throughput: %.3f MB/s\n", throughput);
|
|
}
|
|
fprintf(stderr, "Lines: %d\n", lines);
|
|
|
|
return 0;
|
|
}
|