I have this program, we'll call it Host. Host does all kinds of good stuff, but it needs to be able to accept input through the command line while it's running. This means it has to somehow send its other process data and then quit. For example, I need to be able to do this:
./Host --blahblah 3 6 3 5
This should somehow end up calling some function in Host called
handleBlahBlah(int x1, int y1, int x2, int y2){
//do some more sweet stuff
}
Host is a C program, and does not need to support multiple instances.
An example of this is Amarok music player. With Amarok running and playing, you can type "amarok --pause" and it will pause the music.
I need to be able to do this in Linux or Windows. Preferably Linux.
What is the cleanest way to implement this?
If you were on Windows, I'd tell you to use a hidden window to receive the messages, but since you used ./, I assume you want something Unix-based.
In that case, I'd go with a named pipe. Sun has a tutorial about named pipes that might be useful.
The program would probably create the pipe and listen. You could have a separate command-line script which would open the pipe and just echo its command-line arguments to it.
You could modify your program to support the command-line sending instead of using a separate script. You'd do the same basic thing in that case. Your program would look at it's command-line arguments, and if applicable, open the pipe to the "main" instance of the program, and send the arguments through.
If it needs to be cross-platform, you might want to consider making the running instance listen on a TCP port, and have the instance you fire up from the command-line send a message to that port.
I suggest using either a Unix socket or D-Bus. Using a socket might be faster if you're familiar with Unix sockets programming and only want a few operations, whereas D-Bus might make it easier to concentrate on implementing the functionality in a familiar object-oriented way.
Take a look at Beej's Guide to Unix IPC, particularly the chapter on Unix sockets.
What no one has said here is this:
"you can't get there from here".
The command line is only available as it was when your program was invoked.
The example of invoking "fillinthename arguments ..." to communicate with fillinthename once fillinthename is running can only be accomplished by using two instances of the program which communicate with each other.
The other answers suggest ways to achieve the communication.
An amarok like program needs to detect the existence of another instance
of itself in order to know which role it must play, the major role of
persistent message receiver/server, or the minor role of one shot
message sender.
edited to make the word fillinthename actually be displayed.
One technique I have seen is to have your Host program be merely a "shell" for your real program. For example when you launch your application normally (e.g.: ./Host), the program will fork into the "main app" part of your code. When you launch your program in a way that suggests you want to signal the running instance (e.g.: ./Host --send-message restart), the program will fork into the "message sender" part of your code. It's like having two apps in one. Another option that doesn't use fork is to make Host purely a "message sender" app and have your "main app" as a separate executable (e.g.: Host_core) that Host can launch separately.
The "main app" part of your program will need to open up some kind of a communication channel to receive messages, and the "message sender" part will need to connect to that channel and use it to send messages. There are several different options available for sending messages between processes. Some of the more common methods are pipes and sockets. Depending on your OS, you may have additional options available; for instance, QNX has channels and BeOS/Haiku have BMessages. You may also be able to find a library that neatly wraps up this functionality, such as lcm.
So, I may be missing the point here, but by deafult a C program's main function takes two arguments; argc, a count of the number of arguments (at least one), and argv (or arg vector), the argument list. You could just parse through the arguments and call the correct method.
For example:
int main(int argc, *argv[])
{
/*loop through each argument and take action*/
while (--argc > 0)
{
printf(%s%s, *++argv, (argc > 1) ? " " : "");
}
}
would print all of the arguments to screen. I am no C guru, so I hope I haven't made any mistakes.
EDIT: Ok, he was after something else, but it wasn't really clear before the question was edited. Don't have to jump on my rep...
Related
Given a socket port how do you find the process ID (process name) of the process on Windows 10 that uses this port? I am aware of netstat command but I would like to do it with C code only.
How about there, it appears there's a way: the IP Helper library.
Ref: https://learn.microsoft.com/en-us/windows/win32/iphlp/ip-helper-start-page
I haven't used it for this, but it's clearly going down the right road by providing everything you need to basically roll your own netstat.exe.
The low-level object that contains all the info is MIB_TCPROW2, which has the local and remote address + port, plus dwOwningPid. So we know there's a way.
Drilling down we ultimately need the GetTcpTable2() call, and Microsoft's web page helpfully has what appears to be fully-functional C code to do all this yourself.
https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-gettcptable2
Finding this was the best surprise of my day!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm making a Command-Line Operating system (command line interpreter). How to I get a line of input from the user?
I'm making a Command-Line Operating system. How to I get a line of input form a user?
The first things you'll need are some boot code (to get things like a memory map from firmware), physical memory management, virtual memory management, a scheduler and some kind of inter-process communication (IPC).
The next things you'll need is some kind of device enumeration framework, to help make a tree of devices to keep track of everything; followed by scanning PCI buses to add them to the tree of devices.
Next you'll want to tackle device resources - determining IO port ranges, memory mapped IO ranges and managing IRQs. This can be messy (e.g. AML interpreter for ACPI to determine IO APIC inputs, and "interrupt vector allocator" to handle MSI).
The next thing is USB controller drivers, USB hub driver and maybe (for obsolete hardware) a PS/2 controller driver. These all find devices connected to them (e.g. USB keyboard) and add them to the tree of devices, and then communicate with the drivers for those devices. At some point you might also want to worry about fault tolerance, power management and hot-plug (e.g. if a USB controller driver crashes, is put to sleep or is removed/unplugged; then you'd use the "tree of devices" to figure out which other drivers are effected).
Next, you'll want keyboard drivers. Specifically, a driver for "USB HID" (which is a single specification that covers all human input devices - keyboard, mouse, touchpad, joystick, ..), and maybe (for obsolete hardware) a PS/2 keyboard driver. Note that you'll probably also want an on-screen keyboard for touch-screen users, and input method editor/s to assist with input of some languages (Chinese, Japanese, Korean, etc).
Next, you'll want something for video output. Typically early boot code uses minimal "just enough to display boot log" code (if it's not hidden by a pretty splash image); but you'll want something that's actually good instead (likely including a font engine with Unicode support).
The end result of all of the above is that you'll have a set of (hopefully "standardised for your OS" and documented) device driver interfaces and all of the things that device drivers depend on; a way (the inter-process communication I mentioned near the start) to send "events" (key-presses) to a process and a way for processes to display output (draw things on the screen).
Once all that is done you can write a terminal emulation layer. This is a thing (process?) that hides all the nice modern stuff (e.g. OpenGL, events) under a layer of historic memorabilia (so that the end user's computer, which is likely to be capable of emulating realistic virtual reality environments, can be used as a glorified teleprinter from early last century). This also uses the inter-process communication I mentioned near the start (e.g. maybe pipes - stdin, stdout) to communicate with a child process.
Finally, you can begin writing some sort of command shell. This is just a process that communicates with its parent (e.g. with the terminal emulation layer) via. whatever you're using for inter-process communication (e.g. stdin, stdout) that allows users to start other processes and handles a little "forwarding" (e.g. while a child process is running, keyboard input that shell receives from terminal emulation layer gets forwarded by shell to its child process, and output the shell receives from its child gets forwarded by shell back to shell's parent/terminal emulator).
Note that as part of writing the command shell, or before writing the command shell, you might want to write some libraries to handle simple chores (e.g. getting a whole line of user input and handling things like "home", "end", "delete", "backspace", etc) so that these libraries can be used by all programs including the command shell itself.
It seems doubtful that you are truly implementing an operating system, but if you simply mean a command shell, then it might follow the following structure:
int main()
{
char command_line[1024] ;
char* input = NULL ;
int errorlevel = 0 ;
do
{
// Show command prompt
putchar( '>' ) ;
fflush( stdout ) ;
// Get command line
input = fgets( command_line, stdin, sizeof(command_line) ) ;
if( input != NULL )
{
// Process command line
errorlevel = parseCommand( input, &errorlevel ) ;
}
} while( input != NULL ) ;
return errorlevel ;
}
where parse parseCommand() is a function with the following interface:
int parseCommand( const char* cmd_line, const int* current_errorlevel ) ;
Here the answer to your question of how to get a line of user input is the fgets() function.
The complex part perhaps is in the implementation of parseCommand(); user input is the easy part, but make a start - have fun.
Unlike everyone I appreciate you thinking big but focus on the basics first as it is good to start small. Also, what you are doing is making a command line interpreter and not an OS. There's a big difference between the two. For an OS, you need a kernel, GUI, etc. However here's the solution to your query:
You can use gets, but you might receive a warning in this one
char *gets(char *str)
To overcome above limitation, we can use fgets as :
char *fgets(char *str, int size, FILE *stream)
Using %[^\n]%*c inside scanf
scanf(ā%[^\n]%*cā, str);
This one comes quite in handy when using for loop.
You have a bright future if you think innovatively (people lack this).
But it's always better to brush your base before going big. Welcome to stackoverflow :)
I am coding a linux process that will read input from a serial stream (a GPS module) and perform some actions based on this input.
When developing the program I intend to use a Pseudo Terminal (BSD API) so I can send 'dummy' GPS ascii data to my process and test it. So my master will be my 'GPS Device' and my slave will be my actual linux process that handles the GPS data.
I don't want to fork my process but have 2 different programs (the master and the slave). This way I can separate the code nicely. How can I tell me slave what port name to connect to? Ie; /dev/ttp0 or etc?
Maybe I am using Pseudo Terminal's wrong and should fork them?
ways to pass info (the port number) between processes.
1) use msgsnd()
2) use a pipe()
3) use a mmap area
there are several other methods. I prefer the msgsnd
4) Link to it with a soft link with a fixed name.
For example: /tmp/gpsdevice -> /dev/pts/2. This is trivial to do in the master with symlink.
I am totally new to socket programming and I want to program a combined TCP/UDP-Server socket in C but I don't know how to combine those two.
So at the moment, I do know how TCP- and UDP-Server/-Clients work and I have already coded the Clients for TCP and UDP. I also know that I have to use the select()-function somehow, but I don't know how to do it.
I have to read two numbers, which are sent to the TCP-/UDP-Server with either TCP- or UDP-Clients and then do some calculations with these numbers and then print the result on the server.
Does anyone know a tutorial for that or an example code or can help me with that?
Or at least a good explanation of the select() function.
Basically, use an event loop. It works like this:
Is there anything I need to do now? If so, do it.
Compute how long until I next need to do something.
Call select specifying all sockets I'm willing to read from in the read set and all sockets I'm trying to write to in the write set.
If we discovered any sockets that are ready for reading, read from them.
If we discovered any sockets that are ready from writing, try to write to them. If we wrote everything we need to write, remove them from the write set.
Go to step 1.
Generally, to write to a socket, you follow this logic:
Am I already trying to write to this socket? If so, just add this to the queue and we're done.
Try to write the data to the socket. If we sent it all, we're done.
Save the leftover in the queue and add this socket to our write set.
Three things to keep in mind:
You must set all sockets non-blocking.
Make sure to copy your file descriptor sets before you pass them to select because select modifies them.
For TCP connections, you will probably need your own write queue.
The idea is to mix inside your server a TCP part and a UDP part.
Then you multiplex the inputs. You could use the old select(2) multiplexing call, but it has limitations (google for C10K problem). Using the poll(2)
multiplexing call is preferable.
You may want to use some event loop libraries, like libev (which uses select or poll or some fancier mechanisms like epoll). BTW, graphical toolkits (e.g. GTK or Qt) also provide their own even loop machinery.
Read some good Linux programming book like the Advanced Linux Programming
book (available online) which has good chapters about multiplexing syscalls and event loops. These are too complex to be explained well in a few minutes in such an answer. Books explain them better.
1) Simple write a tcp/udp server code, and when receive the message, just print it out.
2) substitute print code to process_message() function.
Then you have successfully combine TCP and UDP server to the same procedure.
Be careful with your handling procedure, it's should be cope with parellel execution.
You may try this stream_route_handler, it is c/c++ application, you can add tcp/udp handler in your single c/c++ application. This has been using by transportation heavy traffic route, and logging service purpose.
Example of using
void read_data(srh_request_t *req);
void read_data(srh_request_t *req) {
char *a = "CAUSE ERROR FREE INVALID";
if (strncmp( (char*)req->in_buff->start, "ERROR", 5) == 0) {
free(a);
}
// printf("%d, %.*s\n", i++, (int) (req->in_buff->end - req->in_buff->start), req->in_buff->start);
srh_write_output_buffer_l(req, req->in_buff->start, (req->in_buff->end - req->in_buff->start));
// printf("%d, %.*s\n", i++, (int) (req->out_buff->end - req->out_buff->start), req->out_buff->start);
}
int main(void) {
srh_instance_t * instance = srh_create_routing_instance(24, NULL, NULL);
srh_add_udp_fd(instance, 12345, read_data, 1024);
srh_add_tcp_fd(instance, 3232, read_data, 64);
srh_start(instance);
return 0;
}
If you are using C++ program, you may like this sample code.
stream route with spdlog
This is My last question. Now my new requirement is to ping some set of servers and check if they are replying or not. I am trying my way of
system("ping xxx.xx.xx.xx >out.txt");
And then parsing the out.txt for a string "Request timed out.".
This is yielding me good results. But is there any better way to do from c program. Non programmatic ways are also welcome. But mostly I want to go by C program. If the request is timed out I will send a mail through same my way by php. Thanks in advance.
My environment : windows, Tiny C Compiler
A better method for capturing output than system() is to use popen() instead. That way you can capture the output of the command without using a temporary file.
A better method for pinging is to use the Microsoft ICMP API (an introductory page can be found here). This will be possible if your C compiler has the ability to call arbitrary Win32 API functions. In particular, IcmpSendEcho is the function you would want.
Another option is using raw sockets for sending/receiving ICMP packets yourself, or using a library such as libnet for that. You can then take your measurements at a finer granularity. It'll take some time and getting used to, though. :)