Select Git revision
Forked from
sce213ta / mysh-1
1 commit ahead of the upstream repository.

KwonSunyoung authored
commands.c 7.65 KiB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <netdb.h>
#include <sys/un.h>
#define SERVER_PATH "/tmp/server"
#include "commands.h"
#include "built_in.h"
//port number
char port[30];
//thread signal
int end=0;
static struct built_in_command built_in_commands[] = {
{ "cd", do_cd, validate_cd_argv },
{ "pwd", do_pwd, validate_pwd_argv },
{ "fg", do_fg, validate_fg_argv }
};
void *server(void * comm){
struct single_command * com = (struct single_command*)comm;
printf(" Server start\n");
/* TCP/IP
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size;
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(port));
//create socket
serv_sock = socket(PF_INET,SOCK_STREAM,0);
//bind
bind(serv_sock,(struct sockaddr*)&serv_addr , sizeof(serv_addr));
//listen
listen(serv_sock,5);
clnt_addr_size = sizeof(clnt_addr);
//accept
clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);
*/
int sd;
int sd2;
struct sockaddr_un serveraddr;
sd = socket(AF_UNIX,SOCK_STREAM,0);
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path,SERVER_PATH);
bind(sd,(struct sockaddr *)&serveraddr,SUN_LEN(&serveraddr));
listen(sd,5);
/*
struct sockaddr_un cliaddr;
socklen_t len = sizeof(struct sockaddr_un);
*/
sd2 = accept(sd,NULL,NULL);
printf(" accept\n");
int pid;
//server child
if( (pid = fork())== 0 ){
com->argv[com->argc] = NULL;
//dup2(clnt_sock,1);
dup2(sd2,1);
if(strcmp(com->argv[0],"pwd")==0)
{
execv("/bin/pwd",com->argv);
}
else{
execv(com->argv[0],com->argv);
}
}else{
sleep(2);
/*
close(clnt_sock);
close(serv_sock);
clnt_sock=-1;
serv_sock=-1;
*/
close(sd2);
close(sd);
sd=-1;
sd2=-1;
unlink(SERVER_PATH);
printf(" Sent success\n");
end ++;
end ++;
}
}
void *client(void * comm){
sleep(0);
struct single_command* com = (struct single_command *)comm;
printf(" client start\n");
/* TCP/IP
int sock;
struct sockaddr_in serv_addr;
int str_len;
sock = socket(PF_INET,SOCK_STREAM,0);
memset(&serv_addr , 0 , sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
//Domain
struct hostent *host_entry;
int host_ip = 0;
if((host_ip = inet_addr("ajou-VirtualBox"))==-1)
{
host_entry = gethostbyname("ajou-VirtualBox");
if(host_entry != NULL)
host_ip = *((unsigned long *)(host_entry->h_addr_list[0]));
}
serv_addr.sin_addr.s_addr = host_ip;
//TCP/IP("10.0.2.15");
serv_addr.sin_port = htons(atoi(port));
connect(sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
*/
int sock;
struct sockaddr_un serveraddr;
sock = socket(AF_UNIX,SOCK_STREAM,0);
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path,SERVER_PATH);
connect(sock,(struct sockaddr *)&serveraddr,SUN_LEN(&serveraddr));
int pid;
if((pid = fork())==0)
{
com->argv[com->argc]=NULL;
dup2(sock,0);
execv(com->argv[0],com->argv);
}else
{
sleep(2);
close(sock);
sock=-1;
printf(" Client Receive\n");
end++;
}
}
static int is_built_in_command(const char* command_name)
{
static const int n_built_in_commands = sizeof(built_in_commands) / sizeof(built_in_commands[0]);
for (int i = 0; i < n_built_in_commands; ++i) {
if (strcmp(command_name, built_in_commands[i].command_name) == 0) {
return i;
}
}
return -1; // Not found
}
/*
* Description: Currently :
*/
int evaluate_command(int n_commands, struct single_command (*commands)[512])
{
if (n_commands > 0) {
struct single_command* com = (*commands);
// printf("%d %s %s %s \n",com->argc,com->argv[0],com->argv[1],com->argv[2]);
assert(com->argc != 0);
// cd 0 , pwd 1 , fg 2 , another -1
int built_in_pos = is_built_in_command(com->argv[0]);
//modify
if ((built_in_pos != -1)&&(n_commands==1)) {
if (built_in_commands[built_in_pos].command_validate(com->argc, com->argv)) {
if (built_in_commands[built_in_pos].command_do(com->argc, com->argv) != 0) {
fprintf(stderr, "%s: Error occurs\n", com->argv[0]);
}
}else {
fprintf(stderr, "%s: Invalid arguments\n", com->argv[0]);
return -1;
}
}
// another argv[0]
else if (strcmp(com->argv[0], "") == 0) {
return 0;
} else if (strcmp(com->argv[0], "exit") == 0) {
return 1;
} else {
//PIPE MODE
// com->argv[] (com+1)->argv[]
if(n_commands == 2)
{
pthread_t p_thread[2];
int thr_id;
/*
printf("Enter the port number to use (5000~15000)\n");
fgets(port,sizeof(port),stdin);
port[sizeof(port)-1]='\0';
*/
pthread_create(&p_thread[0],NULL,server,(void *)(com));
pthread_create(&p_thread[1],NULL,client,(void *)(com+1));
pthread_detach(p_thread[0]);
pthread_detach(p_thread[1]);
while(end != 3){
sleep(2);
}
sleep(1);
printf("END\n");
end = 0;
return -1;
} // socket
//mode - NO PIPE
else{
// If background process
if(!strcmp(com->argv[(com->argc)-1], "&"))
{
int status;
int pid;
// copy argv
char*copy_argv[(com->argc)];
int c =0;
for(;c<com->argc;c++)
copy_argv[c]=malloc(sizeof(char)*100);
copy_argv[(com->argc)-1] =NULL;
// path copy
for(c=0; c< ( com->argc) -1 ; c++ )
{ strcpy(copy_argv[c],com->argv[c]);
}
/* Double fork version - Hardly know Demon
//1st child
if ((pid = fork() )== 0)
{
sleep(0.8);
//2st child
if( (pid = fork()) == 0 )
{
sleep(0.8);
execv(com->argv[0],copy_argv);
}
else
{
//1st exit
exit(1);
}
}
//parent shell wait
else
{
//foreward process
printf("BackGround process ID %d\n",pid+1);
wait(&status);
}
*/
//child
if( (pid = fork()) == 0 )
{
execv(com->argv[0],copy_argv);
}
//parent no wait only sleep
else{
//child = malloc (sizeof(int*));
*child = pid;
printf("Background pid(%d)\n",pid);
sleep(1);
//copy free
for(c=0; c < com->argc ; c++)
free(copy_argv[c]);
return -1;
}
}
// Start create process - No background
else{
int status;
int pid;
// copy argv
char *copy_argv[(com->argc)+1];
int c =0;
//copy_argv = malloc(sizeof(char*));
for(;c<(com->argc)+1;c++)
copy_argv[c]=malloc(sizeof(char)*100);
//execv last NULL
copy_argv[(com->argc)] = NULL;
for(c=0 ;c < (com->argc) ; c++)
strcpy(copy_argv[c] , com->argv[c]);
//child
if( ( pid = fork() ) ==0 )
{
if(execv(com->argv[0],copy_argv) == -1)
{
printf("execv Fail \n");
exit(0);
}
} // child
//parent
else {
// setbuf(stdin,)
waitpid(pid,&status,0);
char c ;
rewind(stdin);
rewind(stdout);
//free(copy_argv);
for(c=0 ; c< com->argc ; c++)
free(copy_argv[c]);
return -1;
}
}
// NO background create process
/*
fprintf(stderr, "%s: command not found\n", com->argv[0]);
return -1;
*/
} // mode
}
}
return 0;
}
void free_commands(int n_commands, struct single_command (*commands)[512])
{
for (int i = 0; i < n_commands; ++i) {
struct single_command *com = (*commands) + i;
int argc = com->argc;
char** argv = com->argv;
for (int j = 0; j < argc; ++j) {
free(argv[j]);
}
free(argv);
}
memset((*commands), 0, sizeof(struct single_command) * n_commands);
}