하나의 아이디어는 표준 유닉스 유틸리티 tee
의 기능을 모방하는 것입니다, 외부 리디렉션에 의존하지 않고 프로그램 내에서 그렇게 할 수 있습니다.
간단한 함수 mytee()
을 작성 했으므로 효과가있는 것 같습니다. 그것은 shmget(), pipe(), fork(), and dup2()
사용
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
static char *mytee(int size) {
int shmid = shmget(IPC_PRIVATE, size + 1, 0660 | IPC_CREAT);
int pipe_fds[2];
pipe(pipe_fds);
switch (fork()) {
case -1: // = error
perror("fork");
exit(EXIT_FAILURE);
case 0: { // = child
char *out = shmat(shmid, 0, 0), c;
int i = 0;
out[0] = 0;
dup2(pipe_fds[0], 0); // redirect pipe to child's stdin
setvbuf(stdout, 0, _IONBF, 0);
while (read(0, &c, 1) == 1 && i < size) {
printf("<%c>", c); // pass parent's stdout to real stdout,
out[i++] = c; // and then buffer in mycapture buffer
out[i] = 0; // (the extra <> are just for clarity)
}
_exit(EXIT_SUCCESS);
}
default: // = parent
dup2(pipe_fds[1], 1); // replace stdout with output to child
setvbuf(stdout, 0, _IONBF, 0);
return shmat(shmid, 0, 0); // return the child's capture buffer
}
}
내 테스트 프로그램은 다음과 같습니다
는
int main(void) {
char *mycapture = mytee(100); // capture first 100 bytes
printf("Hello World"); // sample test string
sleep(1);
fprintf(stderr, "\nCaptured: <%s>\n", mycapture);
return 0;
}
출력은 다음과 같습니다
<H><e><l><l><o>< ><W><o><r><l><d>
Captured: <Hello World>
응용 프로그램에서이를 사용하려면 mytee()
에서 당신은거야 테스트 문 printf("<%c>", c)
을 (를)(으)로 대체해야합니다..read
으로 전화를 걸면 신호를 처리해야 할 수도 있습니다. 물건의 종류에 참고
close(pipe_fds[0]);
close(pipe_fds[1]);
우수한 짧은 27 세 220 페이지 오라일리 예를 들어, 참조 : 그리고 두 dup2()
년대의 각 후, 당신은 추가 할 수 있습니다 bookDave Curry의 Unix 시스템에서 C 사용.
글쎄, 이미 파이썬으로 끝났지 만 ANSI C로 다시 통합해야합니다. 그래서 다른 프로세스를 호출하는 것 외에는 다른 방법이 없습니까? 스택 높이를 어딘가에 위반하지 않아도되는지 잘 모르겠습니다. – Stasik
C를 사용하는 데 제약이되는 것은 무엇입니까? 좀 더 깔끔한 접근법은 필요한 변경을 수행하는 것보다 (프로그램 라인 사용, OS가 파이프를 지원한다고 가정 할 때) 필터를 통해 프로그램의 출력을 파이프하는 것입니다. – Throwback1986
constrains는 마이크로 컨트롤러의 기존 빌드 및 릴리스 시스템 + 런타임입니다. – Stasik