c - Storing output of called program in buffer -


i'm trying implement remote shell. server supposed read , execute both commands(cd, wait , exit) , programs user enters through client. after executing command or program server supposed send output client.

i'm having problems sending outputs client, store output in buffer , send using write() function, don't know how output of system call or program.

this have far. socket part standard socket implementation have used.

server:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <errno.h> #include <arpa/inet.h>  #define port 9000 #define bufsize 256 #define host "127.0.0.1"  void error(const char *msg) {     perror(msg);     exit(1); }  int main(int argc, char *argv[]) {     int ret, sockfd, newsockfd, portno;     socklen_t clilen;     char buffer[bufsize];     struct sockaddr_in serv_addr, cli_addr;     sockfd = socket(af_inet, sock_stream, 0);     if (sockfd < 0)         error("error opening socket");     size_t sockaddrin_sz = sizeof(struct sockaddr_in);     memset((char*) &serv_addr,  0, sockaddrin_sz);     serv_addr.sin_family = af_inet;     serv_addr.sin_addr.s_addr = inet_addr(host);     serv_addr.sin_port = htons(port);     ret = bind(sockfd, (struct sockaddr *) &serv_addr, sockaddrin_sz);     if (ret < 0)         error("error while binding");     ret = listen(sockfd, 5);     clilen = sizeof(cli_addr);     newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);     if (newsockfd < 0)         error("error on accept");     while(1){         memset(buffer, 0, bufsize);         ret = read(newsockfd, buffer, bufsize -1); // implement here: function split buffer command + arguments, //function calls corresponding system call or calls program, //store output of system call or program in buffer , use write below return output client.                  if (ret < 0)             error("error reading");         if (ret == 0)             break;         fprintf(stdout, "received: %s", buffer);         fflush(stdout);         ret = write(newsockfd, buffer, ret);         if (ret < 0)             error("error writing socket");      }     close(newsockfd);     close(sockfd);     return 0;    } 

client:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <errno.h> #include <arpa/inet.h>  #define port 9000 #define host "127.0.0.1" #define bufsize 256  void error(const char *msg) {     perror(msg);     exit(0); }  int main(void){     int ret, sockfd, portno;     char buffer[bufsize];     struct sockaddr_in srv_addr;     size_t sockaddrin_sz = sizeof(struct sockaddr_in);      srv_addr.sin_family = af_inet;     srv_addr.sin_port = htons(port);     srv_addr.sin_addr.s_addr = inet_addr(host);      sockfd = socket(af_inet,sock_stream, 0);      if (sockfd < 0)         error("couldnt open socket");      ret = connect(sockfd, (struct sockaddr*) &srv_addr, sockaddrin_sz);      if (ret < 0)         error("error couldnt connect socket");      size_t cmd_sz = bufsize -1;     char *cmd = buffer;      while(1){         printf("please enter message: ");          ret = getline(&cmd, &cmd_sz, stdin);          if (ret < 0)             error("couldnt command user");         buffer[ret] = '/0';          ret = write(sockfd, buffer, ret);          if (ret < 0)             error("couldnt write socket");          if (!strcmp("exit\n", buffer))             break;          memset(buffer, 0, bufsize);          ret = read(sockfd, buffer, bufsize - 1);          if (ret < 0)             error("error couldnt read socket");          fprintf(stdout, "%s", buffer);         fflush(stdout);     }     close(sockfd);     return 0;  } 

what i'd write function in server splits input client seperate command arguments, implement functions call corresponding system call based on input , function executes program entered client.

now problem is: how can store output of system calls , called programs in order send output client?

your question, @ time of writing answer, doesn't specify platform examples assume posix operating system. in case either need use decent library (like libevent) or work operating system primitives.

you need @ least following primitives or equivalents:

  • poll() – multiplex input , output in event loop.
  • pipe() – create communication channel.
  • fork() – create new process.
  • close() – close file descriptor.
  • dup() – reuse file descriptor, useful stdin/stdout redirection.
  • exec() – load executable program process.

example: function sets communication channel , runs external command input , output redirected communication channel other end accessible main program.

static bool start_subprocess(char *const command[], int *pid, int *infd, int *outfd) {     int p1[2], p2[2];      if (!pid || !infd || !outfd)             return false;      if (pipe(p1) == -1)             goto err_pipe1;     if (pipe(p2) == -1)             goto err_pipe2;     if ((*pid = fork()) == -1)             goto err_fork;      if (*pid) {             *infd = p1[1];             *outfd = p2[0];             close(p1[0]);             close(p2[1]);             return true;     } else {             dup2(p1[0], 0);             dup2(p2[1], 1);             close(p1[0]);             close(p1[1]);             close(p2[0]);             close(p2[1]);             execvp(*command, command);             /* subprocess error occured. */             fprintf(stderr, "error running %s: %s", *command, strerror(errno));             abort();     }  err_fork:     close(p2[1]);     close(p2[0]); err_pipe2:     close(p1[1]);     close(p1[0]); err_pipe1:     return false; } 

source: https://sourceware.org/git/?p=netresolve.git;a=blob;f=backends/exec.c;hb=head#l44


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -