Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
Using dup2() to redirect output – Kevin Song – UTCS Ph.D Student Kevin Song UTCS Ph.D Student Home Research Teaching Misc Blog Contact Using dup2() to redirect output Sometimes, you want to redirect the output of your program to a file–maybe to record it for another program, or because you want to search through it with grep. If you have to do this at the C level, there are a few ways you can accomplish this. Using a variable Perhaps the simplest way to do this is to use the fprintf family of functions along with a variable that controls what file we want to output to. For example, we can do the following: const char* filename = get_filename_or_null(); // NULL means "use stdout" FILE* outStream; if(filename){ FILE* out = fopen(filename, "w"); if(out){ outStream = out; } else { outStream = stdout; } } else { outStream = stdout; } // Filler code here fprintf(outStream, "my fancy output"); Note that this is a little annoying because we have to specify outStream whenever we want to print. What if we wanted to avoid this variable shenaniganery? Modifying stdout It turns out that on many (though not all!) systems, printf is defined to be something like this: int printf(const char* format, other_args...){ fprintf(stdout, format, other_args...); } Don’t worry too much about the other_args stuff for now. Notice that printf is just fprintf with a FILE* variable called stdout. This suggests that if we overrode the stdout variable, we could get all usages of printf to print to a file. Let’s try it out: const char* filename = get_filename_or_null(); if(filename){ FILE* outputFile = open(filename, "w"); if(outputFile){ stdout = outputFile; } } // Filler code here printf("my fancy output"); Does this work on your system? It works on mine…but this is wildly unsafe to rely on!. All it takes is a different implementation of printf, and output redirection will stop working. These two methods also have the disadvantage that, if you fork-and-exec, they stop working. Let’s take a look at a method that gets rid of all these issues. Using dup2() We can use dup2() to duplicate a file descriptor, which will allow us to redirect output with the following code snippet: const char* filename = get_filename_or_null(); if(filename){ int fd = open(filename, O_WRONLY, 0666); dup2(fd, STDOUT_FILENO); // Check `man stdin` for more info dup2(fd, STDERR_FILENO); // Check the return values of dup2 here } // Filler code here printf("My fancy output"); Notice that this code essentially does the same thing as previously: it redirects output to a file. However, there’s a very important difference here. If the process forks-and-execs, the child process will still have its output redirected to file, even after the exec!. This is something that was not true of our earlier solutions, and is a very useful property of the dup2() solution. Written August 30, 2020 • Last modified January 16, 2021