I have this program that forks and I was wondering how to get it to fork to a separate terminal so the parent and child would have their own windows and stop fighting each other. I am trying to accomplish this with cygwin, any ideas?
The general answer is that it's not possible. However, it can be hacked around by using two different programs, one that does the fork, and then the child executes a new shell which might open a new window, and let that shell run the second program.
Or you can use something like ncurses to split the terminal window into two separate regions and use one region per process.
Related
I am trying to implement background jobs in C for my shell. The problem is it prints the output next to my prompt like this:
user#hostmachine:/.../$: [output]
I have now learnt that "stty tostop" helps suspend process just before it's output but that only works in a shell. I am trying to implement this functionality in C, so that it doesn't use my terminal during a prompt.
I tried to run "stty tostop" after starting my shell but it din't work. I also asked a related question before and now I am stuck here.
Processes in the foreground process group of a given terminal can write to that terminal without being suspended. Others cannot. Thus, to put a process in the background is to put it in a process group other than than one currently in the foreground (setpgrp()).
Use tcsetpgrp() to control which process group is in the foreground on a given terminal. This is part of how you would bring your background process to the foreground.
You might find Glibc's discussion of Implementing a Job-Control Shell useful for more details and related considerations.
I am working on a school project, and though it's not required, I want to implement this functionality. With that said, I can't share code, but I think it's irrelevant in this case.
When using fork(), my understanding is that the child process created inherits stdin and stdout, as the child inherits all the file streams from the parent.
My shell requires background capability, and while it technically already has that, if the "background" program runs, it still receives all the data from stdin and continues output to the screen which is just a jumbled mess. For the record, my instructor's compiled sample shell does the same thing, but I don't want that to happen!
I'm pretty certain I should be using a combination of pipe(), fork(), and dup2(), but I can't put it all together. I understand fork, but I don't understand how pipe or dup2 works and how I should implement it in the shell. I'm thinking something along these lines:
thePipe[2] = pipe();
pid = fork();
close stdin/out on child somehow if backgrounded
But I don't understand the functionality of pipe() or dup2() so I'm stuck.
Thanks!
You don't want pipes here. Processes run in an interactive shell should share their standard file descriptors with the shell — doing otherwise would break a lot more things (including the child processes' ability to determine they're running interactively, and to interact with the tty to handle things like window size changes). It'd also seriously complicate pipelines. Don't do it.
The missing piece here is process groups, which are described in the "General Terminal Interface" section of the Open Group UNIX specs. In brief, the kernel can be made to explicitly recognize a "foreground process group" for the terminal. If a process that isn't in this group tries to read from or write to the terminal, it is automatically stopped.
A brief walkthrough of what is necessary to make a properly functioning shell is available as part of the GNU libc manual, under "Implementing a Job Control Shell". Try following their instructions and see how that goes.
My process launches a process - let it be a shell in this example, but it's applicable to any process really. I need to get notified when the shell creates new processes and to obtain their PIDs.
I can take a snapshot of the whole process tree at any given time (well, pstree can), but how do I monitor creation of new processes by a process with a given PID?
So far I've found several ways to do so at How to monitor an external process for events by its PID in C? none of which really solve my problem:
Monitoring NetLink proc interfaces. Problem: requires root permissions which I do not have.
Custom library overriding the syscalls loaded into the shell process by LD_PRELOAD. Problem: it will be inherited by the children of the shell as well, and I do not want that - I only want to monitor the shell.
ptrace()ing the shell. Problem: flags that notify the parent (i.e. my process) about creating new processes, i.e. PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK and PTRACE_O_TRACECLONE propagate ptrace()ing to child processes, and I only want to monitor the shell.
Making the shell cooperate. Problem: In BASH command callbacks (as used in undistract-me) are very hacky. I'd also prefer to avoid shell-specific code.
I feel like I'm missing something simple here. I feel like I could make one of the above solutions work with more hacks, but... surely I don't have to resort to the big guns like LD_PRELOAD and ptrace() for such a simple task, do I?
JFYI I'm coding this in Vala, but C snippets are welcome too.
No generic solution has been found so far so I had to resort to making the shell cooperate:
ZSH has pre-exec hook documented in
http://zsh.sourceforge.net/Doc/Release/Functions.html
KSH has a
debug hook documented in http://www.manpagez.com/man/1/ksh/
a hack that adds pre-exec to BASH can be found in
https://github.com/jml/undistract-me
I simply write callback commands into the relevant environment variables depending on the shell.
I would like to create a new process of an exe from within the code itself, so that I can have two parallel processes.
But, I would like to them to be separate processes and not parent-child.
Is there a way to do this in C (Windows)?
In Windows, processes don't have parents. Some tools read the InheritedFromUniqueProcessId value, but this does not tell you which process started your process. It only tells you where handles and other attributes were inherited from. In practice however, this value is usually set to the ID of the process that started the child process.
On Vista and above, you can change the InheritedFromUniqueProcessId value by calling CreateProcess with the STARTUPINFOEX structure filled in appropriately: create an attribute list with InitializeProcThreadAttributeList, and add a
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS attribute with UpdateProcThreadAttribute.
On XP, there is no official way of doing this. You can try to use NtCreateProcess or RtlCreateUserProcess, but these don't set up the Win32 subsystem properly so your program might not run.
An ugly way I've done it in the past is to launch a child process, which then launches a second child process, and then the first child exits. This causes the second child to lose any association with the original parent.
I'm sure I later found a better way to do this, but I've gone looking around and can't find anything at the moment.
The "easy" way is to use an intermediate command, see KB here:
http://support.microsoft.com/kb/315939
Another way to have independent processes is to ensure to do not inherit handles to ensure that the 2nd process, and creating a new process group. See Creating independent process!
Most likely forking a new process doesn't exist in windows rather you could use CreateProcess function to do that which is much easier and better option for windows.
If the fork and exec patter is used just to run a program without freeze the current program, what's the advantage, for example, over using this single line:
system("program &"); // run in background, don't freeze
The system function creates a new shell instance for running the program, which is why you can run it in the background. The main difference from fork/exec is that using system like this actually creates two processes, the shell and the program, and that you can't communicate directly with the new program via anonymous pipes.
fork+exec is much more lightweight than system(). The later will create a process for the shell, the shell will parse the command line given and invoke the required executables. This means more memory, more execution time, etc. Obviously, if the program will run in background, these extra resources will be consumed only temporarily, but depending on how frequently you use it, the difference will be quite noticeable.
The man page for system clearly says that system executes the command by "calling /bin/sh -c command", which means system creates at least two processes: /bin/sh and then the program (the shell startup files may spawn much more than one process)
This can cause a few problems:
portability (what if a system doesn't have access to /bin/sh, or does not use & to run a process in the background?)
error handling (you can't know if the process exited with an error)
talking with the process (you can't send anything to the process, or get anything out of it)
performance, etc
The proper way to do this is fork+exec, which creates exactly one process. It gives you better control over the performance and resource consumption, and it's much easier to modify to do simple, important things (like error handling).