今天晚上花了一会写的,开始用的是 argv 是个二位数组, 调程序的时候总是显示不出,后来发现execvp貌似只支持 pointer array =。= 好吧。。。。
程序思路:开子进程以后把 子进程的标准输出 关闭, 然后在子进程中新建一个文件,此时文件会选择 自身进程中最小的文件标识符 作为该文件的文件标识符,也就是fd
程序思路:开子进程以后把 子进程的标准输出 关闭, 然后在子进程中新建一个文件,此时文件会选择 自身进程中最小的文件标识符 作为该文件的文件标识符,也就是fd
所以,以后子进程的所有标准输出都流向了文件, 这个应该是简单的思路了吧,感觉GNU的源码应该是用无名管道,甚至是有名管道(网络传输) 实现的,好吧我就不意淫了。。。 有兴趣的朋友可以去官网上找找 GNU/Linux 的shell 源代码
/* 1.c
* author:wangshiyang
* date: 2013/5/13
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
//------------------------------------------------------
/* for the convience I'v set a lot of global-variables |
* the formal shell program may not dit like this |
* */ // warning: use argv[][] is wrong !!! |
char input[100];// the command you input |
char *argv[30];//the execvp must use point array |
char file[100];//you can input a filename |
//------------------------------------------------------
char *newstr( char *s, int l )
{
char * rv = (char *)malloc( l+1 );
rv[l] = '\0';
strncpy( rv, s, l);
return rv;
}
int deal() // deal the input command
{
char temp[100];
int len, i, a, turn;
fgets(input, 100, stdin);
len = strlen(input);
turn = 0; a = 0;
for( i = 0; i < len; i++ )
{
if( input[i] == '\n' )
{
argv[turn++] = newstr( temp, strlen(temp) );
break;
}
if( input[i] != ' ' )
{
temp[a++] = input[i];
temp[a] = '\0';
}
else
{
argv[turn++] = newstr( temp, strlen(temp) );
a = 0;
}
}
for( i = 0; i < turn; i++ )
if( !strcmp( argv[i], ">" ))
{
strcpy( file, argv[i+1]); //copy the filename to file array
return i;
}
return -1;
};
void execute( int flag ) // run the command
{
int pid, fd;
argv[flag] = NULL;
if( (pid = fork() ) == -1 )
{
perror( "fork" );
exit(1);
}
if ( pid == 0 )
{
/* 0 for stdin, 1 for stdout, 2 for stderr */
close(1); // close the stdout
fd = creat( file, 0777 );// then open and fd connect to 1
execvp( argv[0], argv );// and run
perror( "execvp" );
exit(1);
}
if ( pid != 0 )
{
wait(NULL);
printf( "Father Done\n" );
}
};
void free_all( ) // free all the pointers
{
int i;
for( i = 0; i < 30; i++ )
free(argv[i]);
printf( "All the pointer have been free.." )
};
int main()
{
int flag;
printf( "Please input a command,please using the '>'\n" );
printf( "example: ls -ail > 123 \n" );
flag = deal();
if( flag == -1 )
{
fprintf( stderr, "input wrong! do not include '>'\n");
exit(1);
}
execute( flag );
free_all();
return 0;
}