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
Post a Comment