# I/O redirection 運用 Linux system call 的實作方法 (redirect, pipe, ..) ###### tags: `C LANGUAGE` `I/O redirection` `pipe` `linux` Author: WhoAmI email: kccddb@gmail.com Date: 20220726 Copyright: CC BY-NC-SA ![](https://i.imgur.com/E1oioiz.jpg) ![](https://i.imgur.com/GsMVhhv.jpg) ![](https://i.imgur.com/Q6LBCJZ.jpg) **IO 要注意 conggestion 問題 (高速公路 回堵現象)** ![](https://i.imgur.com/ZX1UOdS.jpg) [Linux I/O 輸入與輸出重新導向,基礎概念教學, by G. T. Wang](https://blog.gtwang.org/linux/linux-io-input-output-redirection-operators/) [dup, dup2, dup3 - duplicate a file descriptor](https://www.man7.org/linux/man-pages/man2/dup.2.html) [Traffic load 與 buffer size 的關係 (QoS)](https://hackmd.io/@pingulinux/load-buffer) ```c= /* **沒有仔細檢查可能的錯誤! 例如 signal,...等 只是了解用法與現象** Author: WhoAmI 20220726 */ /* redirect stdout to "myout.txt" log child process to "myappend.txt" tdup2.c gcc tdup2.c -o tdup2 The exit() function causes normal process termination and the value of status & 0377 is returned to the parent */ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #include <string.h> static int runchild(int fw) { pid_t childpid; char writebuf[128]; time_t t; if((childpid = fork()) == -1) { perror("fork"); exit(EXIT_FAILURE); } if(childpid == 0) { time(&t); sprintf(writebuf,"Child: [%d]output$>pid=%d,fd=%d\n",t,getpid(),fw); write(fw,writebuf,strlen(writebuf)); close(fw); exit(EXIT_SUCCESS); } else { } return(EXIT_SUCCESS); } int main(void) { int newfd0,newfd1, nbytes; char string[128] = "Hello stdout!"; char readbuffer[128]; char writebuf[128]; int fw; int status; time_t current; newfd1=10; fw=open("myout.txt",O_CREAT |O_WRONLY,0666); // Octal 0666 =Binary 110 110 110 if(fw<0){ printf("fw=%d\n",fw); perror("open"); exit(EXIT_FAILURE); } dup2(fw,1); //Be careful! stdout is silently closed before being reused. time(&current); fprintf(stderr,"stderr:localtime:[%s]",ctime(&current)); sprintf(readbuffer,"[%d:%d]output$>%s\n",current,getpid(),string); write(1,readbuffer,strlen(readbuffer)); //write to "myout.txt" if(close(1)<0){ perror("close(1)"); exit(EXIT_FAILURE); } if( close(fw)<0){ perror("close(fw)"); exit(EXIT_FAILURE); }else{ fprintf(stderr,"stderr:We close %d\n",fw); fw=open("myappend.txt",O_CREAT|O_APPEND|O_WRONLY,0666); if(fw>0){ fprintf(stderr,"Open myappend.txt[%d]\n",fw); write(fw,readbuffer,strlen(readbuffer)); //write to "myappend.txt" runchild(fw); time(&current); sprintf(writebuf,"Parent:[%d]output$>pid=%d\n",current,getpid()); write(fw,writebuf,strlen(writebuf)); close(fw); waitpid(-1, &status, 0); //WNOHANG : return immediately if no child has exited. fprintf(stderr,"Get child status=%d\n",status & 0377); } } exit(EXIT_SUCCESS); } ************************************************ /* redirect stdout to "myout.txt" tout.c gcc tout.c -o tout */ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #include <string.h> /* The call ctime(t) is equivalent to asctime(localtime(t)). It converts the calendar time t into a null-terminated string of the form "Wed Jun 30 21:49:08 1993\n" */ int main(void) { int newfd0,newfd1, nbytes; pid_t childpid; char string[] = "Hello stdio! From Child!\n"; char readbuffer[128]; int fw; time_t current; fw=open("myout.txt",O_CREAT |O_WRONLY); if(fw<0){ printf("fw=%d\n",fw); perror("open"); exit(0); } dup2(fw,1); time(&current); fprintf(stderr,"stderr:localtime:[%s]",ctime(&current)); sprintf(readbuffer,"localtime:[%s]virtual output$>%s",ctime(&current),string); write(1,readbuffer,strlen(readbuffer)); if(close(1)<0){ perror("close(1)"); } if( close(fw)<0){ perror("close(fw)"); }else{ fprintf(stderr,"stderr:We close %d\n",fw); } exit(0); } *************************************************** ```