Linux系统的bash程序
—对于标准库和系统库函数的应用
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include <glob.h>
#include <string.h>
#define HOSTSIZE 32
#define PATHSIZE 256
#define CMDSIZE 128
int errfunc(const char *epath,int eerrno)
{
fprintf(stderr,"%s\n",strerror(eerrno));
return 0;
}
void print()
{
struct passwd *usr=NULL;
char hostname[HOSTSIZE];
int res;
char path[PATHSIZE];
char usr_type;
uid_t uid;
size_t dirlen,pathlen;
int i,j;
char *home=path;
uid=getuid();
usr_type=uid==0 ? '#' : '$';
usr = getpwuid(uid);
if(usr == NULL)
{
perror("getpwuid()");
return ;
}
res = gethostname(hostname,HOSTSIZE);
if(res<0)
{
perror("gethostname()");
return ;
}
getcwd(path,PATHSIZE);
if(!strncmp(usr->pw_dir,path,strlen(usr->pw_dir)))
{
sprintf(path,"%c%s",'~',home+strlen(usr->pw_dir));
}
else
strcpy(home,path);
printf("%s@%s:%s%c ",usr->pw_name,hostname,home,usr_type);
}
int cd(char *path,int argc)
{
int res;
struct passwd *usr=NULL;
if(argc == 1)
{
usr = getpwuid(getuid());
if(usr == NULL)
{
perror("getpwuid()");
return -1;
}
chdir(usr->pw_dir);
return 0;
}
res = chdir(path);
if(res < 0)
{
perror("chdir()");
return -1;
}
return 0;
}
int get_commend()
{
char *cmd=NULL;
size_t cmdlen;
ssize_t res;
char *tokres=NULL,*str=NULL;
glob_t glb;
int i;
int flag=0;
pid_t pid;
res = getline(&cmd,&cmdlen,stdin);
if(res < 0)
{
perror("getline()");
return -1;
}
str=cmd;
while(1)
{
tokres=strtok(str," \t\n\0");
if(tokres==NULL)
break;
glob(tokres,GLOB_NOCHECK|(GLOB_APPEND*flag),errfunc,&glb);
flag=1;
str=NULL;
}
glb.gl_pathv[glb.gl_pathc]=NULL;
pid = fork();
if(pid < 0)
{
perror("fork()");
return -2;
}
if(pid == 0)
{
if(strcmp(glb.gl_pathv[0],"cd"))
execvp(glb.gl_pathv[0],glb.gl_pathv);
else
{
cd(glb.gl_pathv[1],glb.gl_pathc);
return -4;
}
perror("execvp()");
return -3;
}
wait(NULL);
globfree(&glb);
free(cmd);
cmd=NULL;
}
int main(viod)
{
char **cmd={'\0'};
while(1)
{
print();
get_commend();
}
exit(0);
}