update: userprog (tee, tsh, sleep, hex2bin)
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h> // isprint
|
||||
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
// Hexdump 헬퍼 함수
|
||||
// offset_base: 전체 스트림에서의 현재 위치 (0x0000, 0x0010 ...)
|
||||
void print_hexdump(const unsigned char *buf, ssize_t len, size_t offset_base) {
|
||||
for (size_t i = 0; i < len; i += 16) {
|
||||
// 1. 오프셋 출력
|
||||
fprintf(stderr, "%08zx: ", offset_base + i);
|
||||
|
||||
// 2. 16진수 출력
|
||||
for (size_t j = 0; j < 16; j++) {
|
||||
if (i + j < len)
|
||||
fprintf(stderr, "%02x ", buf[i + j]);
|
||||
else
|
||||
fprintf(stderr, " "); // 패딩
|
||||
}
|
||||
|
||||
fprintf(stderr, " |");
|
||||
|
||||
// 3. ASCII 출력
|
||||
for (size_t j = 0; j < 16; j++) {
|
||||
if (i + j < len) {
|
||||
unsigned char c = buf[i + j];
|
||||
// 출력 가능한 문자면 출력, 아니면 점(.)
|
||||
fprintf(stderr, "%c", isprint(c) ? c : '.');
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "|\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int *fds = (int *)malloc(sizeof(int) * argc);
|
||||
int fd_count = 0;
|
||||
|
||||
// 모드 플래그
|
||||
int mode_stderr = 0; // --stderr (Raw 출력)
|
||||
int mode_hexdump = 0; // --hexdump (Hex 출력)
|
||||
|
||||
// 1. 인자 파싱
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--stderr") == 0) {
|
||||
mode_stderr = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "--hexdump") == 0) {
|
||||
mode_hexdump = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 일반 파일 열기
|
||||
int fd = open(argv[i], O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd < 0) {
|
||||
perror(argv[i]);
|
||||
continue;
|
||||
}
|
||||
fds[fd_count++] = fd;
|
||||
}
|
||||
|
||||
// 2. 데이터 처리 루프
|
||||
unsigned char buf[BUF_SIZE]; // unsigned로 변경
|
||||
ssize_t n;
|
||||
size_t total_bytes = 0; // 전체 스트림 오프셋 추적용
|
||||
|
||||
while ((n = read(STDIN_FILENO, buf, BUF_SIZE)) > 0) {
|
||||
// (A) STDOUT 출력 (필수: 파이프 연결 유지)
|
||||
if (write(STDOUT_FILENO, buf, n) != n) {
|
||||
perror("write stdout");
|
||||
break;
|
||||
}
|
||||
|
||||
// (B) STDERR 처리 (디버깅용)
|
||||
if (mode_hexdump) {
|
||||
// Hexdump 모드면 예쁘게 포맷팅해서 stderr로
|
||||
print_hexdump(buf, n, total_bytes);
|
||||
} else if (mode_stderr) {
|
||||
// 그냥 stderr 모드면 Raw 데이터를 stderr로
|
||||
if (write(STDERR_FILENO, buf, n) != n) { /* ignore */ }
|
||||
}
|
||||
|
||||
// (C) 파일 출력
|
||||
for (int i = 0; i < fd_count; i++) {
|
||||
if (write(fds[i], buf, n) != n) {
|
||||
perror("write file");
|
||||
}
|
||||
}
|
||||
|
||||
total_bytes += n;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fd_count; i++) {
|
||||
close(fds[i]);
|
||||
}
|
||||
free(fds);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user