I'm trying to exit the console screen i.e close the screen what command can i use to achieve this.
void main()
{
int n;
printf("Please enter a number less than 5");
scanf("%d", &n);
if(n <= 5)
printf("good");
else
{
printf("You entered a number above so the program will exit");
//here i need to call a function or use a command that will close
// the console screen;
}
}
Any help will be appreciated thanks
The C11 standard n1570 does not know about the "console screen" (and I guess you speak of the terminal emulator running your program). Notice that C11 does not mention "screens" or "keyboards" (only standard streams, and very often stdout is not a "console") and many computers (e.g. most Internet servers or supercomputers, or even your mobile phone...) don't have both. Also, your program could be run (even on Windows) with redirections or in a pipeline and then it has no console (so your question don't make any sense in such a common case).
So in general, there is no way to do what you want (since it does not make any sense), in a standard way.
Perhaps your operating system provide some (OS specific) way to achieve that. So investigate the OS API relevant to your system (e.g. WinAPI on Windows, or Linux syscalls -listed in syscalls(2)).
Perhaps you want to use some terminal related library like ncurses.
If your terminal follows the ANSI escape code conventions, you might follow them.
Otherwise, consider making your program having some GUI. For that, you practically need some widget toolkit (such as Qt, GTK, etc..)
You might also consider some inter-process communication with your desktop environment. How to do that (or even its possibility) is very operating-system and desktop specific and might be related to session management.
BTW, remember that stdout is often buffered (and perhaps line-buffered). You'll better end your printf control strings with \n and/or call fflush.
In a windowing operating system or execution environment the console window will close immediately the process terminates, so it is not clear what you are asking here since in your example the program terminates regardless of what input is entered.
If you are running the code from an IDE, often the IDE will create a console process and launch your code within that. In that case the console is not "owned" by your application, but is executed as a child process; in which case the window will remain open until the parent process launched by the IDE is closed. Similarly if you launch your program from a command shell. It is probably unreasonable behaviour for a process to attempt to close its parent even if it is possible.
It is possible to "hide" the console window while the process continues to run, which may be what you are asking; the means of doing that is platform specific, and you have not specified; for Windows such a question would be a duplicate of Win32 programming hiding console window. However it is quite possible that these methods will not work if the process is not launched directly but from some other console process.
in Windows you may simply write code on Notepad, then compile and run it through the Command prompt (cmd.exe). If you have GCC installed as compiler (with all the needed packages), then compile your main.c file as:
gcc main.c -o main.exe
If all went fine, as you run "main", there will be all of your output that you can close or step over for more editing. Bye
PS EDIT -- I see your point: when you launch your .exe from itself, the window closes without giving satisfaction of the messages. You may add a workaround like this before the last curly bracket:
printf("Press any key\n");
scanf("%d");
}
So the output window will still wait for one more input before closing.
You may check for additional information for eg here: https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html
Bye
Related
I noticed that the Unix bc program does not print out it's usual prompt (the three symbols ">>> ") when being started as a background process (like if you execute it as "bc &"). This is confusing to me because from my limited knowledge of Unix, starting a program as a background job will keep it running until as soon as it tries to read from stdin, at which point it will receive a signal to stop itself.
But running bc as a background job ("bc &") will not cause it to at least print out the ">>> " prompt before stopping itself which tells me that the program handles that somehow. I am curious as to how it does this. When I wrote a naive program that only tries to emulate the input/output interaction, it still prints out ">>> " before being suspended which doesn't look very clean at all and the behavior gets even more bizarre on certain shells.
I tried looking through the Unix bc source code and I was able to trace the code to parts where it is printing out the ">>> " prompt, but how it was handling not printing out the prompt when started as a background process was beyond me. And I know that obviously you would never start an input/output interactive program in the background as that goes against intended functionality and common sense, but I am more interested in the concepts behind it like if this was implemented with signal handling and/or if this is some more advanced input/output stream buffering or some other Unix concept that I am not familiar with.
The first thing your version of bc does is call the tcsetattr function. This function, when called from a background process, causes the SIGTTOU signal to be sent to the process, which by default causes the process to stop.
Any program that manipulates terminal attributes (vim, bash, anything that uses readline or curses, ...) will probably behave exactly the same way.
I need to build a console app (A) that shows a menu where you can select an option and it will execute previous console apps (B,C,D...) that i built in class. How can i go about that? can i call these previous apps or do i need to add them into my program?, Because it needs to include about 15 previous projects and i think that's a lil' bit excesive. i know fOpen() is used to open txt files i don't know if it works with apps. FILE *fopen( const char * filename, const char * mode );
You will want to start a child process, then redirect its stdout to your own process' output, and its stdin to your own process' input - but presumably you'll want to intercept certain keystrokes to allow a user to terminate the child process without killing your own.
In a POSIX environment you would use popen() which gives you a pipe for redirecting input and output. On Windows you would use CreatePipe instead. Windows does not implement the POSIX popen() but it does have an internal function _popen but I understand it has different semantics.
But there is no function or capability in the C Standard Library to pipe between processes (C itself doesn't even require the computer to support a concept of a "process" either - it's a surprisingly platform-agnostic language and library - you can even use it for a platform without a malloc implementation).
Anyway, if you're okay with targeting just Windows, or for writing a wrapper library, I recommend you read this MSDN article which describes exactly what you're looking to do:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
Creating a Child Process with Redirected Input and Output
The example in this topic demonstrates how to create a child process using the CreateProcess function from a console process. It also demonstrates a technique for using anonymous pipes to redirect the child process's standard input and output handles. Note that named pipes can also be used to redirect process I/O.
you can use the function system and path the program
example :
system ("ConsoleProgram2.exe"); // if it were in the same path
system() is a shell script method so you can use it as any way you want but people say that is a bad thing to use system function but in you'r case i don't see a problem.
Is it possible to programmatically capture stdout (and stdin) of an already running process on Linux? (Maybe redirect it to a pipe?)
It would be best if the solution worked in userspace (meaning without needing root privileges).
I've seen an answer apparently using gdb, but I'd like to do it without gdb.
EDIT: To clarify: no, I don't have access to the code, neither do I want to change the binary, I want the solution to work from a separate process. The target process is already running anyway.
From inside the process itself (assuming you can change its code in C) you might try freopen(3), perhaps as
FILE*newout = freopen("/some/path", "w", stdout);
if (!newout) { perror("freopen"); exit (EXIT_FAILURE); }
stdout = newout;
See also stdio(3). (Otherwise dup2 the STDOUT_FILENO).
From outside of the process you might perhaps play with /proc/$PID/fd/ that is dup2(2), or redirecting, or tee(1), the /proc/$PID/fd/0 for the stdin of your process $PID, the /proc/$PID/fd/1 for the stdout of your process $PID etc. See proc(5) for more.
Hmmm, note to self: after reading some other similar questions, here are some promising projects which might (?) help me find the answer:
neercs (via)
reptyr (via, via)
injcode (via, via)
If you've already started the process you can use gdb to actually redirect stdout or strace to just intercept the calls to write et.al.
If you don't want to use gdb or strace you would probably need to basically do the same thing as these do. The magic they're doing is to use the ptrace function to trace the other process. This will require that you have the right to trace the program (which also gdb and strace requires), as a normal user you can't trace programs of other users.
Linux Journal has an article about playing with ptrace that shows how you do it. One thing to note is that this will be platform dependent: you have to write the code specifically for the platform you're using, the article seems to have examples for the (32 bit) x86 platform.
I am trying to implement a simple shell in linux and one of the features it should have is to enable to user to press <ctrl+D> and make it stop whatever it is doing - Basicly exactly what <ctrl+C> does in Bash.
Now I was wondering on the easiest way to do this, and I was thinking of some kind of key listener which would make the current task stop. Now the only way I could think of doing this would be to have a separate thread which would force stop and return the main thread to the base state, where it can take new input.
A separate thread would be the only way to "constantly" listen for the correct keypress.
I was hoping for some thoughts on this and possibly a better way to go about it.
[Edit]
I am trying to make a simple shell which can execute external programs, print/change directory, print/set path, print command history, invoke commands from history and print/set/remove command aliases. The CTRL-D is meant to be the equivalent of the CTRL-C in Bash, which allows the user to immediately exit a currently running program, not to exit the shell itself. [/Edit]
Why don't you just handle Ctrl-C?
Here is just one of many SO disussions on trapping the signal: Catch Ctrl-C in C
Ctrl-D generally represents EOF on standard input. You shouldn't mess with it.
If you want the Control-D character to generate an interrupt for you, then:
You need to map the EOF character to something other than Control-D.
You need to map the interrupt character to Control-D.
You do this in POSIX with the <termios.h> header and the functions:
tcgetattr()
tcsetattr()
You'd retrieve the current attributes in a struct termios using tcgetattr(). You'd make a copy of the structure, and modify (for sake of argument) the copy, changing the elements of the c_cc array indexed by VINTR and VEOF (plus any other changes you want to make), and then setting the new attributes using tcsetattr(). You'd also arrange to ensure that you restore the original terminal settings (by another call to tcsetattr() using the original set of attributes retrieved with tcgetattr()) before your shell exits. This might be done by a handler registered with atexit(), or by other mechanisms. You should endeavour to reset the terminal attributes under all circumstances. You can't do anything about a SIGKILL killing you.
While you're testing this, make a little script for yourself:
echo stty $(stty -g) > sane
chmod u+x sane
That records the current (presumably sane) terminal settings in a form that is designed for stty to read reliably. If (when) you have problems with your shell, you can use Control-JsaneControl-J to run the script and reset your terminal back to the known sane settings. This is also useful if you're developing programs that use the curses library.
Unless my comment on the other answer is incorrect, I think what you should do is:
if (!fgets(input, sizeof(input), stdin) == NULL)
{
... do cleanup here ...
exit(0);
}
or something equivalent to that.
I have a console-mode Windows application (ported from Unix) that was originally designed to do a clean exit when it received ^C (Unix SIGINT). A clean exit in this case involves waiting, potentially quite a long time, for remote network connections to close down. (I know this is not the normal behavior of ^C but I am not in a position to change it.) The program is single-threaded.
I can trap ^C with either signal(SIGINT) (as under Unix) or with SetConsoleCtrlHandler. Either works correctly when the program is run under CMD.EXE. However, if I use the "bash" shell that comes with MSYS (I am using the MinGW environment to build the program, as this allows me to reuse the Unix makefiles) then the program is forcibly terminated some random, short time (less than 100 milliseconds) after the ^C. This is unacceptable, since as I mentioned, the program needs to wait for remote network connections to close down.
It is very likely that people will want to run this program under MSYS bash. Also, this effect breaks the test suite. I have not been able to find any way to work around the problem either from within the program (ideal) or by settings on the shell (acceptable). Can anyone recommend anything?
I had the exact same problem - I had written a program with a SIGINT/SIGTERM handler. That handler did clean-up work which sometimes took awhile. When I ran the program from within msys bash, ctrl-c would cause my SIGINT handler to fire, but it would not finish - the program was terminated ("from the outside", as it were) before it could complete its clean-up work.
Building on phs's answer, and this answer to a similar question: https://stackoverflow.com/a/23678996/2494650, I came up with the following solution. It's insanely simple, and it might have some side-effects that I've yet to discover, but it fixed the problem for me.
Create a ~/.bashrc file with the following line:
trap '' SIGINT
That's it. This traps the sigint signal and prevents msys bash from terminating your program "from the outside". However, it somehow still lets the SIGINT signal through to your program, allowing it to do its graceful cleanup/shutdown. I can't tell you exactly why it works this way, but it does - at least for me.
Good luck!
This could be due to the infamous mintty "Input/Output interaction with alien programs" problem (aka mintty issue #56). In this case it is manifesting as Ctrl-C abruptly killing the program rather than being passed down to the program as a signal to be caught and handled. Evidence for this theory is based on zwol's extensive explanation: "console-mode Windows application", "[application is] designed to do a clean exit when it received ^C", "[application] works correctly when the program is run under CMD.EXE" but "[when using the terminal] that comes with MSYS [...] program is forcibly terminated" (at the time of writing (2018) MSYS defaults to using mintty as its terminal).
Unfortunately mintty isn't a full Windows console replacement and various behaviours expected by "native" Windows programs are not implemented. However, you might have some joy wrapping such native programs in winpty when running them within mintty...
Other questions also describe this behaviour: see https://superuser.com/questions/606201/how-to-politely-kill-windows-process-from-cygwin and https://superuser.com/questions/1039098/how-to-make-mintty-close-gracefully-on-ctrl-c .
Arg - 5 minute edit on comment. Here's what I wanted to write:
As a workaround, instead of trying to trap the CTRL-C event which is also being propagated to the shell I'd propose turning off the ENABLED_PROCESSED_INPUT on stdin so that CTRL-C is reported as a keyboard input instead of as a signal:
DWORD mode;
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hstdin, &mode);
SetConsoleMode(hstdin, mode & ~ENABLE_PROCESSED_INPUT); /* disable CTRL-C processing as a signal */
You could then process keyboard input in your main thread while the rest of the program does its thing in a separate thread and set an event to cleanup when CTRL-C is received.
When you run your program with MSYS bash, do you run the executable directly, or is there a wrapping (bash) shell script?
If so, it may be registering a custom Ctrl-C handler with the trap command (that does a sleep followed by a kill.) If such a thing exists, alter or remove it.
If there is no trap registered, or there is no wrapping script, consider making such a script and adding your own trap to override the default behavior. You can see an example of how to use it here or on bash's man page (in the SHELL BUILTINS section).
Ctrl-C is SIGINT? I thought Ctrl-Z was SIGINT, but Ctrl-C is SIGTERM. Check that.
Do you have a CYGWIN environment setting (in control panel/environment variables)? Try setting CYGWIN=notty and restart open a new MSYS bash shell - does the problem persist?