I have a front-end X program, in this program , a background program a.out is called. In a.out, there are some printf sentences. I found the standard outputs are saved in ~/.xsession-errors. Is it normal? I don't want to save these printf contents. Is there any method to avoid saving them except deleting printf?
Yes, you can use the freopen(3) function to redirect stdout to some other file, or to the null device if you'd rather not have any output:
// Discard all further output to standard output for the duration of the
// program (or until the next call to freopen()):
stdout = freopen("/dev/null", "w", stdout);
Depending on how the child program is launched, you can also just redirect its stdout stream. If you're launching it with system(3), you can just use shell redirection:
system("./a.out args >/dev/null");
If you're launching it with a fork() and exec() pair, then you can redirect the stdout file descriptor in between the fork() and exec() to avoid changing anything in the parent process:
// Error checking omitted for expository purposes
pid_t pid = fork();
if(pid == 0)
{
// Child process
int fd = open("/dev/null", O_WRONLY);
dup2(fd, STDOUT_FILENO);
close(fd);
execve("./a.out", argv, envp);
}
There are a few possibilities, by no means an exhaustive list:
When you run your child program, do so in such a way that standard output/error is sent to the bitbucket, such as system ("myprog >/dev/nul 2>&1");.
Include in that child program your own printf varargs-type function which basically does nothing. Provided that function is included before any attempt is made to link in the C runtime libraries, it will use your dummy one in preference.
Use freopen to redirect standard output and error to the same bitbucket.
Options 2 and 3 require changes to the child program which may or may not be desirable. The first option can be effected by only changing the parent program.
In a similar situation I had done this:
#define printf(...) ;
Related
pid_t pid;
pid = fork(); //Two processes are made
const char* ptr = secondlinecopy;
if (pid > 0 && runBGflag==0) //Parent process. Waits for child termination and prints exit status
{
int status;
if (waitpid(pid, &status, 0) == pid && WIFEXITED(status))
{
printf("Exitstatus [");
for (int i = 0; i < noOfTokens; i++)
{
printf("%s ", commands[i]);
}
printf("\b] = %d\n", WEXITSTATUS(status));
}
}
else if (pid == 0) //Child process. Executes commands and prints error if something unexpected happened
{
printf("why does this only print when an invalid command is supplied?");
if (runBGflag==1) insertElement(getpid(),ptr);
execvp(commands[0], commands);
printf ("exec: %s\n", strerror(errno));
exit(1);
}
In the code excerpt we see a process creation via fork(). When execvp is supplied a real command, such as "ls" for example, we get the output.
/home/kali/CLionProjects/clash/cmake-build-debug: ls
clash CMakeCache.txt cmake_install.cmake Testing
clash.cbp CMakeFiles Makefile
Exitstatus [ls] = 0
However, if we supply an invalid command, the output will be:
/home/kali/CLionProjects/clash/cmake-build-debug: sd
why does this only print when an invalid command is supplied?exec: No such file or directory
Exitstatus [sd] = 1
Why is that the case? Shouldnt the process always call printf("Why does ...") first and then run exec?
Why is that the case? Shouldnt the process always call printf("Why does ...") first and then run exec?
Let's say it works like this:
printf(...) --> internal buffer --(fflush? newline? max_buffer_size?)--> output
Usually stdout is line buffered and your printf has no newline. The data to-be-printed are stored inside some internal buffer. When exec-ing the stdout is not fflushed and the parent process is replaced by child process as it is as a whole - so all the data stored in parent process, including some internal stdout state, are removed. When exec fails, stdout is flushed when you printf(...\n" (or after calling exit() when stdout is block buffered) and the data show up. Research: studio buffering modes and setvbuf() function.
Why is that the case? Shouldnt the process always call printf("Why does ...") first and then run exec?
Yes, it should, and you've not presented any reason to think that it doesn't.
printf directs output to the standard output stream, and that defaults to being line buffered when it is connected to an interactive device, or to being block buffered otherwise. When execvp() succeeds, it replaces the whole program image with that of a new program, including the contents of any I/O buffers. Any data that have been buffered but not flushed to the underlying device are lost.
When execvp() fails and the program thereafter terminates normally (regardless of its exit status) all then-buffered buffered data is automatically flushed to the relevant output device.
You would see different behavior if you appended a newline to the message you are printing, or if you called fflush(stdout) between the printf and execvp calls, or if you printed to stderr instead of to stdout, or if you turned off buffering of stdout.
I have a function which create two child process. In the first child process I am writing in a file and in the second one I am also writing in a file which is different from the first one.
In the dad process I am executing the function execvp.
What I need is the stdout and stderrof the function execvp, so that the two child process can write in files what goes out from stderr and stdout. Then at the end I am merging the two files.
I would like to know where I should close pipes and where I should use wait so that I don't have problem using function read and write and such that I don't go in a infinite loop. I didn't implement the functions that create files, the function that merge files and the function that run the shell instruction because I am just wondering if this is the best structure for the function createTwoChild.
As aligned on the comments I'm providing a skeleton here (simplified just for stdout):
if (pipe(fd)<0) goto my_sys_error; // just an example to get out of here
if ((pid_child=fork())<0) {
close(fd[0]); close(fd[1]);
goto my_sys_error; // you can also use something like e.g. "return -1" to handle the error
}
if (!pid_child) {
// the child process with exec() of which we want to get the output
close(fd[0]); close(0);
dup2(fd[1],1); close(fd[1]);
execXX(...); // some of exec() family also spawn a shell here
close(1);
_exit(127); // This must not happen
}
// master/parent
close(fd[1]); // master doesn't need, only child writes to it
i = read(fd[0],p,PIPEBUF_SIZE);
if (i>0) {
// usual handling, write to file, do whatever you like
// should be while() instead of if(), just simplified
} else {
// handle it, e.g. print "no data from extcmd"
}
close(fd[0]); // close the last fd
waitpid(pid_child, &status_child, 0);
if (!WIFEXITED(status_child)) {
kill(pid_child,SIGKILL);
}
Some notes:
This is actually a simplified implementation of popen().
When the child exited then you will get an EOF on read - in this simple way no sighandler for SIGCHLD is required.
Other signal handling not covered.
stderr can be simply added with an additional pipe.
I'm trying to implement a Linux pipe chain in C. For example:
grep file | ls | wc
So, there is a code that splits the arguments into tokens with the pipe as the separator, and sends each part to the following function with an integer specifying whether it precedes a pipe or not:
int control_flow(char** args, int precedes){
int stdin_copy = dup(0);
int stdout_copy = dup(1);
// if the command and its args precedes a pipe
if (precedes){
int fd[2];
if (pipe(fd) == -1){
fprintf(stderr, "pipe failed\n");
}
if (dup2(fd[1], 1)!=1)
perror("dup2 error 1 to p_in\n"); // 1 points to pipe's input
status = turtle_execute(args); // executes the argument list, output should go into the pipe
// Code stops running here
if (dup2(fd[0], 0)!=0)
perror("dup2 error 0 to p_out\n"); // 0 points to pipe's output, any process that reads next will read from the pipe
if (dup2(stdout_copy, 1)!=1)
perror("dup2 error 1 to stdout_copy\n"); // 1 points back to stdout
}
// if the command does not precede a pipe
else{
status = turtle_execute(args); // input to this is coming from pipe
if (dup2(stdin_copy, 0)!=0) // 0 points back to stdin
perror("dup2 error 1 to stdin_copy");
}
return 0;
}
My code stops running after the first command executes. I suspect it is necessary to fork a process before using this pipe, why is that? If so, how do I do that in my code without changing what I intend to do?
Edit:
This is roughly what turtle_execute does:
turtle_execute(args){
if (args[0] is cd or ls or pwd or echo)
// Implement by calling necessary syscalls
else
// Do fork and exec the process
So wherever I have used exec, I have first used fork, so process getting replaced shouldn't be a problem.
The exec system call replaces the current process with the program you are executing. So your process naturally stops working after the turtle_execute, since it was replaced with the new process.
To execute a new process you normally fork to create a copy of the current process and then execute in the copy.
When you are in the shell, normally each command you type is forked and executed. Try typing exec followed by a command into a shell and you will find that the shell terminates once that command has finished executing, since it does not fork in that case.
Edit
I suggest you have a look at the example on the pipe(2) man page (http://man7.org/linux/man-pages/man2/pipe.2.html#EXAMPLE). It shows the usual way of using a pipe:
Calling pipe to get the create the pipe
Calling fork to fork the process
Depending on whether it is child or parent close one end of the pipe and use the other
I think your problem might be that you make the writing end of your pipe the stdout before forking, causing both the parent and the child to have an open writing end. That could prevent an EOF to be sent since one writing end is still open.
I can only guess what happens in most of turtle_execute, but if you fork, exec on one process, and wait for it on the other, without consuming data from the pipe, it might fill the pipe and to the point where writing is blocked. You should always consume data from the pipe while you write to it. It is a pipe after all and not a water tank. For more information have a look at the pipe(7) man page under the 'Pipe capacity' section.
My end goal is to have a parent process pass lines of text to the child, then the child process will print the text to stdout. The child is to run "permanently" in the back ground while the parent gets user input and pass's it to the child. I prefer the child in a separate program. Differentiating between child and paretn through if statements is messy as fudge.
I was looking into pipes but I'm unsure if it's even possible for pipes to communicate between a parent/child after the child has called exec() to a different program.
Is this possible? If so, is there any example you can point me to? If not, what method of IPC can I use in that case?
The standard scenario is to have the program executed as a child be agnostic of the pipe and just use stdin / stdout. You achieve this by dup2()ing the respective end of the pipe as fd 0 or 1 (or both with two pipes for bidirectional communication), corresponding to STDIN_FILENO and STDOUT_FILENO. After this, exec your child program.
Of course, there are alternatives like e.g. "named pipes" if you need stdin / stdout for a different purpose in the child.
Still if you write both parts yourself, you might want to think about simpler solutions:
Differentiating between child and parent through if statements is messy as fudge.
You have to do this anyways, at least for wiring up the pipes and calling exec(). Just create separate code files and call things like parent_main() and child_main() as appropriate (whatever you like to call them).
After exec*() functions the child shares all the file descriptors of the parent process. So if you create a pipe before fork() you have access to read/write fd in both of them.
Usual method is:
create a pipe (a read fd, a write fd)
fork()
in parent:
close read fd (you will not read from parent here)
write data into write fd
wait/die
in child:
close write fd (you will not write from child)
read data from read fd
wait/die
Can't see why you want to exec a new process. If really needed you have to use standard stdin/stdout (see other answer) or have a program that will accept a fd (filedescriptor, an integer) as parameter in order to know which one is the pipe. Don't seems very nice to me.
Actually it is much easier to do it with popen which manages the communication channels automatically
FILE *popen(const char *command, const char *mode);
The popen() function shall execute the command specified by the string
command. It shall create a pipe between the calling program and the
executed command, and shall return a pointer to a stream that can be
used to either read from or write to the pipe.
The environment of the executed command shall be as if a child process
were created within the popen() call using the fork() function, and
the child invoked the sh utility using the call:
execl(shell path, "sh", "-c", command, (char *)0);
where shell path is an unspecified pathname for the sh utility.
The popen() function shall ensure that any streams from previous
popen() calls that remain open in the parent process are closed in the
new child process.
The mode argument to popen() is a string that specifies I/O mode:
If mode is r, when the child process is started, its file descriptor
STDOUT_FILENO shall be the writable end of the pipe, and the file
descriptor fileno(stream) in the calling process, where stream is the
stream pointer returned by popen(), shall be the readable end of the
pipe.
If mode is w, when the child process is started its file descriptor
STDIN_FILENO shall be the readable end of the pipe, and the file
descriptor fileno(stream) in the calling process, where stream is the
stream pointer returned by popen(), shall be the writable end of the
pipe.
If mode is any other value, the result is undefined.
After popen(), both the parent and the child process shall be capable
of executing independently before either terminates.
Pipe streams are byte-oriented.
RETURN VALUE
Upon successful completion, popen() shall return a pointer to an open
stream that can be used to read or write to the pipe. Otherwise, it
shall return a null pointer and may set errno to indicate the error.
For example suppose you want to send Hello world to the child:
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main()
{
FILE* toChild;
toChild = popen("./child", "w");//child is executable of the other file: change the name
int res = fputs( "Hello World\n", toChild);
pclose(toChild);
return 0;
}
and the child:
int main()
{
char p[100];
int n;
do{
n = scanf("%s", p);
if (n>0) {
printf("INPUT MESSAGE: \"%s\n\"", p);
//free(p);
}
else {
printf( "%d, No matching characters\n", n);
}
}while(n>0);
return 0;
}
You can also use scanf("%ms", &p) with char* p and then free(p) if you are on a pure POSIX system (not on OSX).
I am writing some C code that involves the use of pipes. To make a child process use my pipe instead of STDOUT for output, I used the following lines:
close(STDOUT);
dup2(leftup[1], STDOUT);
However, it seems to go into some sort of infinite loop or hang on those lines. When I get rid of close, it hangs on dup2.
Curiously, the same idea works in the immediately preceding line for STDIN:
close(STDIN);
dup2(leftdown[0], STDIN);
What could be causing this behavior?
Edit: Just to be clear...
#define STDIN 0
#define STDOUT 1
Edit 2: Here is a stripped-down example:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#define STDIN 0
#define STDOUT 1
main(){
pid_t child1 = 0;
int leftdown[2];
if (pipe(leftdown) != 0)
printf("ERROR");
int leftup[2];
if (pipe(leftup) != 0)
printf("ERROR");
printf("MADE PIPES");
child1 = fork();
if (child1 == 0){
close(STDOUT);
printf("TEST 1");
dup2(leftup[1], STDOUT);
printf("TEST 2");
exit(0);
}
return(0);
}
The "TEST 1" line is never reached. The only output is "MADE PIPES".
At a minimum, you should ensure that the dup2 function returns the new file descriptor rather than -1.
There's always a possibility that it will give you an error (for example, if the pipe() call failed previously). In addition, be absolutely certain that you're using the right indexes (0 and 1) - I've been bitten by that before and it depends on whether you're in the parent or child process.
Based on your edit, I'm not the least bit surprised that MADE PIPES is the last thing printed.
When you try to print TEST 1, you have already closed the STDOUT descriptor so that will go nowhere.
When you try to print TEST 2, you have duped the STDOUT descriptor so that will go to the parent but your parent doesn't read it.
If you change your forking code to:
child1 = fork();
if (child1 == 0){
int count;
close(STDOUT);
count = printf("TEST 1\n");
dup2(leftup[1], STDOUT);
printf("TEST 2 (%d)\n", count);
exit(0);
} else {
char buff[80];
read (leftup[0], buff, 80);
printf ("%s\n", buff);
sleep (2);
}
you'll see that the TEST 2 (-1) line is output by the parent because it read it via the pipe. The -1 in there is the return code from the printf you attempted in the child after you closed the STDOUT descriptor (but before you duped it), meaning that it failed.
From ISO C11 7.20.6.3 The printf function:
The printf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.
Multiple thing to mention,
When you use fork, it causes almost a complete copy of parent process. That also includes the buffer that is set up for stdout standard output stream as well. The stdout stream will hold the data till buffer is full or explicitly requested to flush the data from buffer/stream. Now because of this , now you have "MADE PIPES" sitting in buffer. When you close the STDOUT fd and use printf for writing data out to terminal, it does nothing but transfers your "TEST 1" and "TEST 2" into the stdout buffer and doesn't cause any error or crash (due to enough buffer). Thus even after duplicating pipe fd on STDOUT, due to buffered output printf hasn't even touched pipe write end. Most important, please use only one set of APIs i.e. either *NIX or standard C lib functions. Make sure you understand the libraries well, as they often play tricks for some sort of optimization.
Now, another thing to mention, make sure that you close the appropriate ends of pipe in appropriate process. Meaning that if say, pipe-1 is used to communicate from parent to child then make sure that you close the read end in parent and write end in child. Otherwise, your program may hung, due to reference counts associated with file descriptors you may think that closing read end in child means pipe-read end is closed. But as when you don't close the read end in parent, then you have extra reference count for read end of pipe and ultimately the pipe will never close.
There are many other things about your coding style, better you should get hold on it :)
Sooner you learn it better it will save your time. :)
Error checking is absolutely important, use at least assert to ensure that your assumptions are correct.
While using printf statements to log the error or as method of debugging and you are changing terminal FD's (STDOUT / STDIN / STDERR) its better you open a log file with *NIX open and write errors/ log entries to it.
At last, using strace utility will be a great help for you. This utility will allow you to track the system calls executed while executing your code. It is very straight forward and simple. You can even attach this to executing process, provided you have right permissions.