How to use pseudo-terminals in Linux with C? - c

I'm trying to figure out how to use pseudo-terminal's in linux, essentially I want to create a telnetd clone, something I mentioned in an earlier question.
I understand the concept of master and slave terminal, and I have a basic grasp on how to use syscalls in C.
My question concerns the next step after opening a slave / master file descriptor. How to I launch getty in the slave? Are there any good resources on the net for using the forkpty(), openpty(),or another API?
Some examples in C would help. This was a very similar question, but no one really provided any examples.

Advanced Programming in the Unix Environment, 2nd Edition has a superb chapter on the pseudo-terminal layer available in Linux. The best part is the source code which contains a pty driver and very clearly demonstrates how to use the pty interfaces. (The pty program it builds is useful in its own right if you want to drive a terminal-only program programmatically but don't wish to use expect(1).)

include
#include <sys/stat.h>
#include <fcntl.h>
#define _XOPEN_SOURCE
#include <stdlib.h>
int main(int argc, char **argv)
{
char *slavename;
int masterfd;
masterfd = open("/dev/ptmx", O_RDWR);
grantpt(masterfd);
unlockpt(masterfd);
slavename = ptsname(masterfd);
...
}
I posted simple example of demonstrating pseudo terminal master slave concept. please go through this link to get clear understanding of terminals in Linux
http://www.linusakesson.net/programming/tty/

You don't lauch a getty for ptys. The getty is only the "listener" part of the process. For hardwired terminals, each individual terminal-device is "listening" constantly. For telnet, the daemon does the listening part(on a socket), and handles connection request by creating a pty pair, and fork()ing / exec()ing.
And indeed: APUE handles ptys very well.

Related

Enabling seccomp strict mode gets "Invalid Argument" error on Replit

I am making an online code judge using Replit, and I want to use seccomp to securely run submitted code.
Through reading a few tutorials, I have made a simple test program to test seccomp:
#include <stdio.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
int main(){
prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
printf("Message #1\n");
fork();
printf("Message #2\n");
}
When I run the program, Message #2 prints twice, which must mean seccomp didn't do it's job of stopping the fork. When I investigate using strace, I notice the following message within the output, though I am not sure what to do with it:
...
prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT) = -1 EINVAL (Invalid argument)
...
How can I fix this problem, and get seccomp running in strict mode? I do not own a Linux machine, so I am not sure if this problem is specific to Replit, or I am doing something wrong.
Seccomp is already in use on replit. Make your program do prctl(PR_GET_SECCOMP);, or check /proc/self/status, and you'll see it's already active and in filter mode. While I don't see anything about that in prctl's man page, I do in seccomp's (which fails the same way if you try syscall(SYS_seccomp, SECCOMP_SET_MODE_STRICT, 0, NULL);):
EINVAL A secure computing mode has already been set, and
operation differs from the existing setting.
So if you want to use seccomp strict mode, you'll need to do so somewhere else. Setting up a Linux VM on your computer is easy and free, so that's what I'd recommend.

How do I get PID from socket port on Windows?

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!

How to open a serial port with read/write lines reversed?

I know how to open a serial port using 'open' function:
open("/dev/portname", flags)
But I want two programs to open this port but with reversed read/write lines. For example when program 2 writes something to the port, program 1 can read it.
If you're using a Unix-like operating system, and if you don't need full serial port semantics, named pipes can be quite useful for doing this sort of thing.
If you need more control, you could perhaps use a pair of pseudoterminals, with a third program running in the background shuttling characters between the master ends.
And do see the related question "Virtual Serial Port for Linux" that the StackOverflow machinery already found for you.
You cannot typically do that in software.
Such things are normally done by hardware, and that is what cross-over cables and "null-modem" cables are good for.

C: How to check if the computer is locked/sleep?

Is there any function in C to check if the computer is going to sleep,hibernate or locked and waking up from these state?
In msdn they provided for C#, C++ but not for C.
My OS is windows7
Like below is the code I'm using to check the time duration between starting the program and terminating it(shutting down the system will terminate the program so this way time duration can be measured).
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include<time.h>
clock_t start_time=0;
void bye (void)
{
FILE *read,*write;
write=fopen("F:\\count.txt","w");
clock_t end_time=clock();
fprintf(write,"Time: %d",(end_time-start_time)/CLOCKS_PER_SEC);
fclose(write);
}
int main (void)
{
start_time=clock();
atexit (bye);
//exit (EXIT_SUCCESS);
getch();
}
In the same way I want to check for locked/sleep/hibernate.
One possible way to wrap the c++ code(provided in the link) in c as mentioned by #ddriver
But is it not possible in C at all?
The WinAPI has generally at least the same possibilities as .NET framework. What your are asking for is the PowerManagement API.
You will have to register to receive PowerSettingNotificationEvents with the RegisterPowerSettingNotification function. Unfortunately, it is used differently for a GUI application where you give a handle to a window that will then receive a WM_POWERBROADCAST message each time the system is about to change state (one of the suspend modes or the hibernate mode), and for a non GUI (typically a service) that registers a HandlerEx callback with a dwControl parameter of SERVICE_CONTROL_POWEREVENT and a dwEventType of PBT_POWERSETTINGCHANGE.
The link you provide is about signals, emitted when power mode is changing. So, obviously, you can check when the system is about to go to sleep, or it just woke up.
As of checking if the system currently sleeps, that is simply not possible, as user code will simply not be running during deep sleep states. Maybe some platform specific, very low level BIOS API, but those are usually not public, and far from portable.

Send messages to program through command line

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...

Resources