Why does printf output show up in a command prompt? - c

We all know the basic Hello World program:
#include <stdio.h>
int main() {
printf("Hello World!");
return 0;
}
This will open up a command prompt and show us the "Hello, World" message.
My question is: Why? Why is the message shown in a command prompt and not in notepad for example? Why not as a Windows notification? Why is it specifically the command prompt and not something else?

When you “open” a file through Window’s File Explorer, the system (not necessarily the OS directly; various subcomponents are involved) examines the file. If it is a native Windows application, the system will execute it directly. If it is another kind of file, the system will look up an appropriate application for it. For example, if it is a Microsoft Word file, the system will start Microsoft Word with a request that it open the file.
If the file is a “command line” program, the system will start Windows Terminal (or similar program in various versions of Microsoft Windows) with a request to run the program. More specifically, it may start Windows Terminal with a request to run a particular command-line shell and to have that shell run your program.
The C language grew up in Unix-like environments where a command shell read input from a physical keyboard and write output to a physical display. In modern systems, these are usually replaced by pseudo-devices that perform the same functions in software. When the shell starts a command-line program, it creates a new process with the standard input and standard output streams of that process connected to the pseudo-device that provides the keyboard/display functions. (This is the default. You can also request a shell to start a program with input and output redirected from/to files and other devices.)
Then, when your program writes to standard output, it goes to the pseudo-device, which relays the data to the appropriate parts of the system that cause the text to be displayed in the terminal window.

Related

How do I hide a shell window in Linux?

I'm developing an application using C that should run on Windows and Linux. This application should hide the shell it runs from. On Windows I was able to fix it by calling the ShowWindow function but on Linux I can't find a way to achieve the same effect.
void main(void)
{
do_stuff();
#ifdef _WIN32
ShowWindow(GetConsoleWindow(), SW_HIDE);
#else
// Linux hide current console
#endif
while(1)
{
do_other_stuff();
}
}
In linux, the "console" (I put quotes around the word for reasons explained below) you call is not such a console, but another application that runs separate of the main application, so you don't have normally full control of it (because the application doesn't know if it is running from the actual system console, from an xterm(1) application, gnome-terminal application, and the like)
Assume you are launching your application from an ssh connection to a remote server, with the DISPLAY environment variable indicating the X11 server to display the info. In that case, the command shell that spawns your application is not a graphical environment "console" but a local shell running on a ssh session started from a remote connection that is completely out of control.
Note about the term "console": The Windows term "console" makes reference to the common POSIX shell interface of starting a process with three (in windows, five) open file descriptors, standard input, standard output, and standard error (in MS-DOS also standard printer and standard communications port) descriptors to allow by default the program to read from its standard input, and write to its standard output and standard error. The term console comes from the fact that, in MS-DOS, (MS-DOS made an improvement from CP/M by making similar system calls as UNIX to read and write to descriptors) all this stuff happened on the console, so they selected (this time in windows) the term "a Windows console application" as a Windows normal application normally didn't provide this interface. For that, Windows requires your program to be linked as a "Windows console" this means to link a special library that opens a Windows window (under control of the application) and makes all input, output and standard error to go there. This makes Windows console applications being capable of controlling the console, as it is an application window, not the case of Linux, that can be, or can be not.
In UNIX systems, the term console applies to a special device (of similar characteristics that the ones used for user sessions) in which the kernel used to start communications with the administrator (something like ---but not equal--- the standard input, standard output and standard error of the kernel) A special device, normally attached to a printer, to show the kernel messages about device errors or kernel security messages. UNIX systems have normally many text devices attached and only one is selected as the console of the system, but due to this difference from Windows machines, Microsoft decided to reinterpret the term to their convenience. Probably a wrong, but accepted decision.

Journalctl to .txt file from C program

I have a application written in C and i want to control writing of syslogs in txt file from application. On application there is option for START/STOP running, so basically when i press START i want to start writing syslog(journalctl) to /some_folder/debug.txt, and when i press STOP i want to close the file.
This can be done by linux command "journalctl [parameter] > /some_folder/debug.txt", but that is not enough, this must be controlled from application.
Does anyone have idea how this can be done properly, is there some API to control syslogs or i have to do it via system()?
If there is no way, if i have to use system() and journalctl commands are there some suggestion which commands to use?

Redirect programs directly to eclipse console

I am using eclipse cdt oxygen with mingw64 7.2.0 on windows 10 to write programs in c. Whenever I write programs that only outputs like:
printf("x\n");
The output got printed into the console. However when I write programs that asks for inputs, like:
c = getchar();
rather than going to the console, eclipse instead opens a terminal. I believe that is where you will type the input. This doesn't usually bother me, however my eyes are destroyed, I am using a screen reader and this terminal is somewhat inaccessible. It is usable, but can be very hard to use sometimes (E.G. my screen reader JAWS does not speak what I'm typing).
Is there a way for eclipse cdt to put all inputs and outputs directly to the console?
Unfortunately in this case eclipse console is read only. Better once compile and build your code go to the folder where it created your exe file and run that exe in command prompt and test.
open command prompt window (type cmd)
cd C:\path_to_your_exe\
yourexe
This will also help you in case your program takes command line parameters.

equivalent of /dev/kmsg on windows?

I want to add a custom line to windows kernel log, from a batch file, or from cmd prompt.
In linux, I would do this by writing to /dev/kmsg file. Anything written to that file would be visible via dmesg or /var/log/messages.
e.g. echo Hello world > /dev/kmsg
I want something very similar for windows side.
I am also OK if there is a solution like log_to_kernel.exe "my message", instead of redirecting to a device file. I think, there isn't concept of device "files" in windows.
The reason for requirement:
I am trying to debug some issues in a driver & for that I am running some test program, which internally makes calls to the driver in windows.
If the driver fails, I will be able to see the debug messages in the kernel windbg attached over 1394. The kernel debugger will hit a breakpoint/assert & I will not be able to check the iteration number on my target system, till I continue from windbg.
Hence I need to log the time & the test iteration number in kernel log itself, which I am planning to do via the batch file, which runs the automated tests.
Hence, I need some tool or dummy echo driver with C code, which would log my custom message in the kernel log.
In one line, I want to write a custom message to kernel log, from a user space app.
You are supposed to use DbgPrintEx function to write log entries if you are writing a driver,
http://msdn.microsoft.com/en-us/library/windows/hardware/ff543634(v=vs.85).aspx
Then the debugger should be able to display it.
If your application is user mode, OutputDebugString is the simplest,
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363362(v=vs.85).aspx
You might also read about event tracing,
http://msdn.microsoft.com/en-us/library/windows/desktop/bb968803(v=vs.85).aspx

Starting process in new Terminal window on Mac

On Windows I can do CreateProcess(..., CREATE_NEW_CONSOLE, ...) and my child process (which is console app, not GUI) will be launched in a new window. What is the easiest way to emulate this on Mac OS?
open -a Terminal.app $(which program) gets a new terminal running the specified program (assuming you're using bash).
You can use execve() (possible after a fork()) to acheive the same thing in compiled code without knowing any Apple APIs (I imagine there is a proper way to do this...).
Read man open.
Edit: you don't need to specify the path to Terminal.app (the finder can figure that out).
If you have X running, it is even easier: just spawn a new xterm with xterm -e program &.
Read man xterm (which will take longer...).
I'll second Chris about the correct use (or lack thereof) of CLI for ordinary mac programs. In my buisness this is expected but the typical user will be {confused|angry|unhappy}.
The Terminal (Terminal.app, what you're referring to as "the console") is just another user-level application on Mac OS X, not a capability of the operating system. There is no direct way in the various APIs available on Mac OS X to just start an executable within a new Terminal window.
However, I believe you can open an executable with Terminal as if it was a document — whether in code or as a user — and it will run in a new session. However, this is not a normal Mac OS X user experience and should not generally be used in Mac software you're going to deliver to end users.
Mac OS X applications are applications. It's fine to provide tools that advanced users can interact with via Terminal, but Terminal is in no way, shape or form a substitute for a real application when delivering software to end users.
I'll add to this that if you're using Cocoa, you can use the NSTask class to start and interact with another process very easily.
Marc Liyanage does this neatly with "term", osascript tell application "Terminal":
http://www.entropy.ch/blog/Mac+OS+X/2005/02/28/Terminal_tricks_8220_term_8221_and_8220_clone_8221.html
(On "typical users": there are different universes, each finding the others strange.
Coming from Unix, I'm used to a process or "| pipe args" anywhere a file can be used;
this helps software componentry immensely.
But open -a does files only -- different universe).

Resources