- system.c
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
int
system(const char *cmdstring) /* version without signal handling */
{
pid_t pid;
int status;
if (cmdstring == NULL)
return(1); /* always a command processor with Unix */
if ( (pid = fork()) < 0) {
status = -1; /* probably out of processes */
} else if (pid == 0) { /* child */
execl("/bin/sh", "sh", "-c", cmdstring, (char *) 0);
_exit(127); /* execl error */
} else { /* parent */
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR) {
status = -1; /* error other than EINTR from waitpid() */
break;
}
}
return(status);
}
- Variable Number of arguments in C function calls
/* This example illustrates how to write a function that uses a*/
/* variable number of arguments such as printf or execl.*/
/* This is an Implementation of execl in terms of execv */
/* It was taken from section 5 of the manual supplied with the system.*/
/* man 5 varargs */
#include
#include
#define MAXARGS 100
#define NULL ((char *)0)
main(){
int myexecl();
execl("/bin/ls", "ls", "-l", "-r", "-t", NULL);
/* execl is called by
execl(file, arg1, arg2, ..., (char *)0);
*/
}
execl(va_alist)
va_dcl
{
va_list ap;
char *file;
char *args[MAXARGS]; /* assumed big enough*/
int argno = 0;
va_start(ap);
file = va_arg(ap, char *);
while ((args[argno++] = va_arg(ap, char *)) != 0)
;
va_end(ap);
return execv(file, args);
}
- Shell Implementation
- write prompt
- read command line
- parse into linked list of words
- perform substitutions
- remap Standard IO
- build argv
- fork/exec
- cshell history substituion
- table of previous commands
- !! - redo
- !$ - it
- !n
- !str
- !str:word_select
- cshell history word selection
- !str:word_select
- !str:s/pat/replacement/
- cshell alias substitution
- cshell command substitution
- cshell variable substitution
- set w=/class/csce510/Examples
- cd $w
-
- profile files
- .login .cshrc .logout .tcshrc
- .profile
- Remapping stdio
- FILE *freopen(char *filename, char *type; FILE *stream) [fdopen]
- noclobber in csh; >!
- Example/freopentest.c
#include
main(){
FILE *fp, *fopen();
fprintf(stdout,"Print to STDOUT\n");
dumpfile(stdout);
freopen("junk","w", stdout);
fprintf(stdout,"Print to STDOUT\n");
dumpfile(stdout);
}
dumpfile(fp)
FILE *fp;
{
fprintf(stderr, "\nFILE structure\n _cnt %d\n _ptr %d\n _base %d",
fp ->_cnt, fp->_ptr, fp->_base);
fprintf(stderr, "\n _flag %d\n _file %d",
fp ->_flag, fp->_file);
}
/*
typedef struct {
int _cnt;
unsigned char *_ptr;
unsigned char *_base;
char _flag;
char _file;
} FILE;
*/
- remapping with dup
- Example/remapStderr.c
#include
main(){
FILE *fp1, *fp2;
void *fatal();
freopen("junk", "w", stdout);
close (2);
dup (1);
execlp("wc", "wc", "junk", "jjjbar", "junk", (char *) 0);
}
void *
fatal(char *str){
fprintf(stderr, "%s\n", stderr);
}
- Pipes
- system maintained buffer for communication between processes
- int pipe (int fd[2]);
- pipesize in limits.h
- Examples: pipe0.c
#include
main(){
int pfd[2];
pid_t p;
if(pipe(pfd) < 0) fatal("Pipe failed");
if((p = fork()) < 0)fatal("Fork failed");
if(p == 0){
close(0);
dup(pfd[0]);
close(pfd[1]);
close(pfd[0]);
execlp("wc", "wc", (char*)0);
} else{
close(1);
dup(pfd[1]);
close(pfd[0]);
close(pfd[1]);
execlp("ls", "ls", (char*)0);
}
}
- Examples: pipesize.c
#include
#include
main(){
printf("PIPE BUF SIZE is =%d\n", PIPE_BUF);
}
- popen
- FILE *popen(char *cmd, char *type);
- popen pipes/forks/sets up pipe/ execs cmd
- Examples/popen.c
#include
main(){
FILE *fp, *popen();
char str[1024];
fp = popen("date","r");
fgets(str, 1024, fp);
fprintf(stdout, "%s", str);
}
- Implementation
FILE *popen(cmd, mode)
char *cmd, *mode;
{
FILE *fp, *fdopen();
int pfd[2];
int pid;
if(pipe(pfd) < 0) fatal("Pipe failed");
if(*mode == 'r'){
if((pid = fork()) < 0){ fatal("Fork failed");
}else if (pid == 0){
close(pfd[0]);
close(1);
if(dup(pfd[1]) != 1) fatal("Dup returned non STDOUT");
execlp(cmd, cmd, NULL);
fatal("Exec failed");
}else{
if((fp = fdopen(pfd[0],"r")) == NULL) fatal("Fdopen failed");
return(fp);
}
}else if(*mode == 'w'){
}else{
fatal("popen mode must be 'r' or 'w'");
}
}
- I/O redirection in Shells
- \<
- \>
- \>\>
- |
- \> & (in bash >2)
- Signals Overview