Можно ли перенапривить ввод/вывод запущенного процесса в linux socket в реальном времени?
Можно ли перенаправить ввод/вывод запущенного процесса в socket. Linux, С, СPP.
То есть программно запустить процесс и управлять им через сокет удаленно в реальном времени, а не получить результат выполнения?
Встречал упоминания по запросам. Хочется открыть порт на сервере, подключиться клиентом и управлять им, что-то вроде обратного ssh простыми запросами. Ну должно же быть решение или хотя бы наброски куда копать.
Наберитие "man unix", там в конце пример клиент-серверного приложения общающихся по unix-сокету. Весь man нельзя выложить, но вот пример:
spoiler
EXAMPLE
The following code demonstrates the use of sequenced-packet sockets for local interpro‐
cess communication. It consists of two programs. The server program waits for a connec‐
tion from the client program. The client sends each of its command-line arguments in
separate messages. The server treats the incoming messages as integers and adds them up.
The client sends the command string "END". The server sends back a message containing
the sum of the client's integers. The client prints the sum and exits. The server waits
for the next client to connect. To stop the server, the client is called with the com‐
mand-line argument "DOWN".
The following output was recorded while running the server in the background and repeat‐
edly executing the client. Execution of the server program ends when it receives the
"DOWN" command.
Example output
$ ./server &
[1] 25887
$ ./client 3 4
Result = 7
$ ./client 11 -5
Result = 6
$ ./client DOWN
Result = 0
[1]+ Done ./server
$
int
main(int argc, char *argv[])
{
struct sockaddr_un name;
int down_flag = 0;
int ret;
int connection_socket;
int data_socket;
int result;
char buffer[BUFFER_SIZE];
/*
* In case the program exited inadvertently on the last run,
* remove the socket.
*/
ret = connect (data_socket, (const struct sockaddr *) &addr,
sizeof(struct sockaddr_un));
if (ret == -1) {
fprintf(stderr, "The server is down.\n");
exit(EXIT_FAILURE);
}
/* Send arguments. */
for (i = 1; i < argc; ++i) {
ret = write(data_socket, argv[i], strlen(argv[i]) + 1);
if (ret == -1) {
perror("write");
break;
}
}
/* Request result. */
strcpy (buffer, "END");
ret = write(data_socket, buffer, strlen(buffer) + 1);
if (ret == -1) {
perror("write");
exit(EXIT_FAILURE);
}
/* Receive result. */
ret = read(data_socket, buffer, BUFFER_SIZE);
if (ret == -1) {
perror("read");
exit(EXIT_FAILURE);
}
/* Ensure buffer is 0-terminated. */
buffer[BUFFER_SIZE - 1] = 0;
printf("Result = %s\n", buffer);
/* Close socket. */
close(data_socket);
exit(EXIT_SUCCESS);
}
For an example of the use of SCM_RIGHTS see cmsg(3).
SEE ALSO
recvmsg(2), sendmsg(2), socket(2), socketpair(2), cmsg(3), capabilities(7), creden‐
tials(7), socket(7), udp(7)
COLOPHON
This page is part of release 5.00 of the Linux man-pages project. A description of the
project, information about reporting bugs, and the latest version of this page, can be
found at https://www.kernel.org/doc/man-pages/.
Задача в теме была описана. Запустить интерактивный (не завершающийся сразу, требующий ввода от пользователя) процесс, и управлять вводом-выводом через сокет.
Задача в теме была описана. Запустить интерактивный (не завершающийся сразу, требующий ввода от пользователя) процесс, и управлять вводом-выводом через сокет.
Попробую объяснить по другому. Нашел рабочий пример перенаправления ввода-вывода в сокет. При подключении клиента, "ls" выполнится, результат будет отправлен клиенту. Задача же в другом, можно ли до завершения процесса (если раскомментировать блок с тем же man unix внизу), передать управление так, чтобы можно было получить вывод man и отправить через сокет "q", для выхода из man?
for (;;)
{ /* loop, accepting connections */
if ( (csock = accept( serverSockfd, NULL, NULL )) == -1)
exit(1);
cpid = fork();
if (cpid < 0) exit(1); /* exit if fork() fails */
if ( cpid )
{
/* In the parent process: */
close( csock ); /* csock is not needed in the parent after the fork */
waitpid( cpid, NULL, 0 ); /* wait for and reap child process */
}
else
{
/* In the child process: */
printf("execvp\n");
dup2( csock, STDOUT_FILENO ); /* duplicate socket on stdout */
dup2( csock, STDERR_FILENO ); /* duplicate socket on stderr too */
close( csock ); /* can close the original after it's duplicated */
char *cmd = "/usr/bin/man";
char *cmdArgs[] = { "man",
"unix",
NULL }; //note: last item is NULL
/*
char *cmd = "ls";
char *cmdArgs[] = { "ls",
"/home/user",
NULL }; //note: last item is NULL
*/
execvp( cmd, cmdArgs ); /* execvp() the command */
}
}