Reputation:
I am currently working on a ssh program and I want to be able to have full control over the terminal via networking. My question is, if I send a command to the server to run in the terminal, how do I get the output that the terminal prints? I have seen many posts saying to use the popen()
command but from what I have tried I can't change directories and do other commands using this, only simple things such as ls
. Is there any other way to get output from terminal besides sending it to a file like command > filetoholdcommand
. Thanks in advance!
Upvotes: 1
Views: 4643
Reputation: 8550
I would put this as a comment, but I dont have enough rep as I'm new. cd is a built in shell command so you want to use system(). But cd will have no effect on your process (you have to use chdir(), for that),so what you really want to do is start a shell as a subprocess via fork/exec, connect pipes to it stdin and stdout,then pipe it commands for the duration of the user session or connection.
Following code give the general idea. Basic, and flawed - use select() not usleep() for one.
int argc2;
printf( "Server started - %d\n", getpid() );
char buf[1024] = {0};
int pid;
int pipe_fd_1[2];
int pipe_fd_2[2];
pipe( pipe_fd_1 );
pipe( pipe_fd_2 );
switch ( pid = fork() )
{
case -1:
exit(1);
case 0: /* child */
close(pipe_fd_1[1]);
close(pipe_fd_2[0]);
dup2( pipe_fd_1[0], STDIN_FILENO );
dup2( pipe_fd_2[1], STDOUT_FILENO );
execlp("/bin/bash", "bash", NULL);
default: /* parent */
close(pipe_fd_1[0]);
close(pipe_fd_2[1]);
fcntl(pipe_fd_2[0], F_SETFL, fcntl(pipe_fd_2[0], F_GETFL, NULL ) | O_NONBLOCK );
while(true)
{
int r = 0;
printf( "Enter cmd:\n" );
r = read( STDIN_FILENO, &buf, 1024 );
if( r > 1 )
{
buf[r] = '\0';
write(pipe_fd_1[1], &buf, r);
}
usleep(100000);
while( ( r = read( pipe_fd_2[0], &buf, 1024 ) ) > 0 )
{
buf[r-1] = '\0';
printf("%s", buf );
}
printf("\n");
}
}
Upvotes: 3
Reputation: 8247
You want the "popen" function. Here's an example of running the command ls /etc
and outputting to the console.
#include <stdio.h> #include <stdlib.h> int main( int argc, char *argv[] ) { FILE *fp; int status; char path[1035]; /* Open the command for reading. */ fp = popen("/bin/ls /etc/", "r"); if (fp == NULL) { printf("Failed to run command\n" ); exit; } /* Read the output a line at a time - output it. */ while (fgets(path, sizeof(path), fp) != NULL) { printf("%s", path); } /* close */ pclose(fp); return 0; }
Upvotes: 1