Skip to content

Instantly share code, notes, and snippets.

@defp
Created May 27, 2012 07:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save defp/2802677 to your computer and use it in GitHub Desktop.
Save defp/2802677 to your computer and use it in GitHub Desktop.
linux simple shell
*.pyc
*~
*.[oa]
*.db
*.*~
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global
# Ignore bundler config
/.bundle
# Ignore the default SQLite database.
/db/*.sqlite3
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp
a.out
testfile*
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, const char *argv[])
{
pid_t pid;
int i, fd;
char *buf = " This is a daemon";
/* 第一步 */
pid = fork();
if (pid < 0) {
perror("fork error\n");
}
else if (pid > 0) {
exit(0); /*父进程退出*/
}
setsid(); /* 创建新会话*/
chdir("/"); /* 改变目录*/
umask(0); /*重设文件权限掩码*/
for (i = 0; i < getdtablesize(); i++) {
/*getdtablesize() 返回所在进程的文件描述附表的项数,即该进程打开的文件*/
close(i); /* 关闭打开的文件*/
}
/* 守护进程工作*/
while(1) {
if ((fd = open("tmp/daemon.log",
O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0) {
printf("open file error\n");
exit(1);
}
write(fd, buf, strlen(buf) + 1);
close(fd);
sleep(10);
}
return 0;
}
/* execute.c - code used by small shell to execute commands */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
int execute(char *argv[])
/*
* purpose: run a program passing it arguments
* returns: status returned via wait, or -1 on error
* errors: -1 on fork() or wait() errors
*/
{
int pid ;
int child_info = -1;
if ( argv[0] == NULL ) /* nothing succeeds */
return 0;
if ( (pid = fork()) == -1 )
perror("fork");
else if ( pid == 0 ){
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
execvp(argv[0], argv);
perror("cannot execute command");
exit(1);
}
else {
if ( wait(&child_info) == -1 )
perror("wait");
}
return child_info;
}
#include <stdio.h>
#include <unistd.h> /* 提供系统调用的定义*/
#include <sys/types.h> /*提供类型pid_t 的定义*/
int main(int argc, const char *argv[])
{
pid_t result;
result = fork();
/* 通过result的值判断返回情况*/
if (result < 0) {
perror("fork error\n");
}
/*result 为0 代表子进程*/
else if (result == 0) {
printf("The result value is %d\n Chird Pid is %d\n",result, getpid() );
}
/* 返回值大于0代表父进程*/
else {
printf("The result value is %d\n father pid is %d\n",result, getpid());
}
return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, const char *argv[])
{
int i;
for (i = 0; i < 10; i++) {
printf("my pid is %d, i = %d\n", getpid(), i);
sleep(1);
if (fork() != 0) {
exit(0);
}
}
return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
int fd;
int pid;
char msg1[] = "test 1 23 \n";
char msg2[] = "helloworld1 23 \n";
if ((fd = creat("./tesefile", 0644)) == -1)
return 0;
if (write(fd, msg1, strlen(msg1)) == -1)
return 0;
if ((pid = fork()) == -1)
return 0;
if (write(fd,msg2,strlen(msg2)) == -1)
return 0;
close(fd);
return 1;
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
FILE *fp;
int pid;
char msg1[] = "test 1 23 \n";
char msg2[] = "helloworld1 23 \n";
if ((fp = fopen("testfile3","w")) == NULL) {
return 0;
}
fprintf(fp,"%s",msg1);
fflush(fp);
if ((pid = fork()) == -1) {
return 0;
}
fprintf(fp,"%s",msg2);
fclose(fp);
return 1;
}
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int i;
printf("parent pid is %d\n",getpid());
if (fork() != 0) {
exit(0);
}
for (i = 0; i <= 10; i++) {
printf("hello my pid is %d \n", getpid());
sleep(1);
}
/* */
return 0;
}
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main(){
pid_t pid;
int pipe_fd[2];
char buf[MAX_DATA_LEN];
const char data[] = "pipe test";
int real_read, real_write;
memset((void *)buf, 0, sizeof(buf));
/* 创建管道*/
if(pipe(pipe_fd) < 0){
printf("pipe create error\n");
exit(1);
}
if((pid = fork()) == 0 ) {
close(pipe_fd[1]);
/*子进程关闭写描述符*/
sleep(DELAY_TIME * 3);
if ((real_read = read(pipe_fd[0], buf, MAX_DATA_LEN)) >0) {
printf("%d bytes read from the pipe is '%s'\n", real_read, buf);
}
close(pipe_fd[0]);
exit(0);
}
else if (pid >0) {
/* 关闭父进程读描述符 */
close(pipe_fd[0]);
sleep(DELAY_TIME);
if ((real_write = write(pipe_fd[1], data, strlen(data))) != -1) {
printf("parent wrote %d bytes:'%s'\n", real_write, data);
}
close(pipe_fd[1]);
waitpid(pid, NULL, 0);
exit(0);
}
}
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#define MAXARGS 20
#define ARGLEN 100
int main(int argc, const char *argv[])
{
char * arglist[MAXARGS + 1];
int numargs;
char argbuf[ARGLEN];
char * makestring();
numargs = 0;
while (numargs < MAXARGS) {
printf("Arg[%d]\n",numargs);
if(fgets(argbuf, ARGLEN, stdin) && * argbuf != '\n') {
arglist[numargs++] = makestring(argbuf);
}
else {
arglist[numargs] = NULL;
execute(arglist);
numargs = 0;
}
}
return 0;
}
int execute(char *arglist[])
{
pid_t pid;
int exitstatus;
pid = fork();
switch(pid)
{
case -1:
perror("fork error");
exit(1);
/* 子进程执行*/
case 0:
execvp(arglist[0],arglist);
perror("execvp faild");
exit(1);
default:
while (wait(&exitstatus) != pid ) {
;
printf("chiled exited with status %d,%d\n", exitstatus >> 8, exitstatus&0377);
}
}
}
char * makestring(char *buf)
{
char * cp, * malloc();
buf[strlen(buf)-1] = '\0';
cp = malloc(strlen(buf)+1);
if (cp == NULL) {
fprintf(stderr, "no memory\n");
exit(1);
}
strcpy(cp,buf);
return cp;
}
#define YES 1
#define NO 0
char *next_cmd();
char **splitline(char *);
void freelist(char **);
void *emalloc(size_t);
void *erealloc(void *, size_t);
int execute(char **);
void fatal(char *, char *, int );
int process();
/** smsh1.c small-shell version 1
** first really useful version after prompting shell
** this one parses the command line into strings
** uses fork, exec, wait, and ignores signals
**/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "smsh.h"
#define DFL_PROMPT "> "
int main()
{
char *cmdline, *prompt, **arglist;
int result;
void setup();
prompt = DFL_PROMPT ;
setup();
while ( (cmdline = next_cmd(prompt, stdin)) != NULL ){
if ( (arglist = splitline(cmdline)) != NULL ){
result = execute(arglist);
freelist(arglist);
}
free(cmdline);
}
return 0;
}
void setup()
/*
* purpose: initialize shell
* returns: nothing. calls fatal() if trouble
*/
{
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
}
void fatal(char *s1, char *s2, int n)
{
fprintf(stderr,"Error: %s,%s\n", s1, s2);
exit(n);
}
/** smsh2.c - small-shell version 2
** small shell that supports command line parsing
** and if..then..else.fi logic (by calling process())
**/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include "smsh.h"
#define DFL_PROMPT "> "
int main()
{
char *cmdline, *prompt, **arglist;
int result, process(char **);
void setup();
prompt = DFL_PROMPT ;
setup();
while ( (cmdline = next_cmd(prompt, stdin)) != NULL ){
if ( (arglist = splitline(cmdline)) != NULL ){
result = process(arglist);
freelist(arglist);
}
free(cmdline);
}
return 0;
}
void setup()
/*
* purpose: initialize shell
* returns: nothing. calls fatal() if trouble
*/
{
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
}
void fatal(char *s1, char *s2, int n)
{
fprintf(stderr,"Error: %s,%s\n", s1, s2);
exit(n);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include "smsh.h"
#include "varlib.h"
/**
** small-shell version 4
** first really useful version after prompting shell
** this one parses the command line into strings
** uses fork, exec, wait, and ignores signals
**/
#define DFL_PROMPT "> "
int main()
{
char *cmdline, *prompt, **arglist;
int result, process(char **);
void setup();
prompt = DFL_PROMPT ;
setup();
while ( (cmdline = next_cmd(prompt, stdin)) != NULL ){
if ( (arglist = splitline(cmdline)) != NULL ){
result = process(arglist);
freelist(arglist);
}
free(cmdline);
}
return 0;
}
void setup()
/*
* purpose: initialize shell
* returns: nothing. calls fatal() if trouble
*/
{
extern char **environ;
VLenviron2table(environ);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
}
void fatal(char *s1, char *s2, int n)
{
fprintf(stderr,"Error: %s,%s\n", s1, s2);
exit(n);
}
/** sol08.8a.c
** ------------------------------------------------------------
A small extension of waitdemo1.c to create and wait for
two child processes is
sol08.8a.c.
Watching the order of output messages from this program
helps clarify the fact that the processes are running in
parallel and writing to the same output stream.
** ------------------------------------------------------------
**
**
* A version of waitdemo1.c that creates and waits for two children.
*
* build: cc sol08.8a.c -o sol08.8a
*/
#include <stdio.h>
#define DELAY 2
#define oops(s,x) { perror(s); exit(x); }
main()
{
int newpid1, newpid2;
void child_code(), parent_code();
printf("before: mypid is %d\n", getpid());
if ( (newpid1 = fork()) == -1 )
oops("fork",1);
if ( newpid1 == 0 )
child_code(DELAY);
if ( (newpid2 = fork()) == -1 )
oops("fork",2);
if ( newpid2 == 0 )
child_code(DELAY);
parent_code(newpid1, newpid2);
return 0;
}
/*
* new process takes a nap and then exits
*/
void child_code(int delay)
{
printf("child %d here. will sleep for %d seconds\n", getpid(), delay);
sleep(delay);
printf("child done. about to exit\n");
exit(17);
}
/*
* parent waits for child then prints a message
*/
void parent_code(int child1, int child2)
{
int wait_rv; /* return value from wait() */
printf("waiting for %d and %d\n", child1, child2);
wait_rv = wait(NULL);
printf("Wait returned: %d\n", wait_rv);
wait_rv = wait(NULL);
printf("Wait returned: %d\n", wait_rv);
}
/* splitline.c - commmand reading and parsing functions for smsh
*
* char *next_cmd(char *prompt, FILE *fp) - get next command
* char **splitline(char *str); - parse a string
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "smsh.h"
char * next_cmd(char *prompt, FILE *fp)
/*
* purpose: read next command line from fp
* returns: dynamically allocated string holding command line
* errors: NULL at EOF (not really an error)
* calls fatal from emalloc()
* notes: allocates space in BUFSIZ chunks.
*/
{
char *buf ; /* the buffer */
int bufspace = 0; /* total size */
int pos = 0; /* current position */
int c; /* input char */
printf("%s", prompt); /* prompt user */
while( ( c = getc(fp)) != EOF ) {
/* need space? */
if( pos+1 >= bufspace ){ /* 1 for \0 */
if ( bufspace == 0 ) /* y: 1st time */
buf = emalloc(BUFSIZ);
else /* or expand */
buf = erealloc(buf,bufspace+BUFSIZ);
bufspace += BUFSIZ; /* update size */
}
/* end of command? */
if ( c == '\n' )
break;
/* no, add to buffer */
buf[pos++] = c;
}
if ( c == EOF && pos == 0 ) /* EOF and no input */
return NULL; /* say so */
buf[pos] = '\0';
return buf;
}
/**
** splitline ( parse a line into an array of strings )
**/
#define is_delim(x) ((x)==' '||(x)=='\t')
char ** splitline(char *line)
/*
* purpose: split a line into array of white-space separated tokens
* returns: a NULL-terminated array of pointers to copies of the tokens
* or NULL if line if no tokens on the line
* action: traverse the array, locate strings, make copies
* note: strtok() could work, but we may want to add quotes later
*/
{
char *newstr();
char **args ;
int spots = 0; /* spots in table */
int bufspace = 0; /* bytes in table */
int argnum = 0; /* slots used */
char *cp = line; /* pos in string */
char *start;
int len;
if ( line == NULL ) /* handle special case */
return NULL;
args = emalloc(BUFSIZ); /* initialize array */
bufspace = BUFSIZ;
spots = BUFSIZ/sizeof(char *);
while( *cp != '\0' )
{
while ( is_delim(*cp) ) /* skip leading spaces */
cp++;
if ( *cp == '\0' ) /* quit at end-o-string */
break;
/* make sure the array has room (+1 for NULL) */
if ( argnum+1 >= spots ){
args = erealloc(args,bufspace+BUFSIZ);
bufspace += BUFSIZ;
spots += (BUFSIZ/sizeof(char *));
}
/* mark start, then find end of word */
start = cp;
len = 1;
while (*++cp != '\0' && !(is_delim(*cp)) )
len++;
args[argnum++] = newstr(start, len);
}
args[argnum] = NULL;
return args;
}
/*
* purpose: constructor for strings
* returns: a string, never NULL
*/
char *newstr(char *s, int l)
{
char *rv = emalloc(l+1);
rv[l] = '\0';
strncpy(rv, s, l);
return rv;
}
void
freelist(char **list)
/*
* purpose: free the list returned by splitline
* returns: nothing
* action: free all strings in list and then free the list
*/
{
char **cp = list;
while( *cp )
free(*cp++);
free(list);
}
void * emalloc(size_t n)
{
void *rv ;
if ( (rv = malloc(n)) == NULL )
fatal("out of memory","",1);
return rv;
}
void * erealloc(void *p, size_t n)
{
void *rv;
if ( (rv = realloc(p,n)) == NULL )
fatal("realloc() failed","",1);
return rv;
}
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
ARGLEN shell.c 7;" d file:
DELAY sol08.8a.c 20;" d file:
DELAY_TIME pipe.c 8;" d file:
DFL_PROMPT smsh1.c 13;" d file:
DFL_PROMPT smsh2.c 12;" d file:
DFL_PROMPT smsh4.c 16;" d file:
MAXARGS shell.c 6;" d file:
MAX_DATA_LEN pipe.c 7;" d file:
NO smsh.h 2;" d
YES smsh.h 1;" d
child_code sol08.8a.c /^void child_code(int delay)$/;" f
child_code wait_8.8.c /^ void child_code(){$/;" f
emalloc splitline.c /^void * emalloc(size_t n)$/;" f
erealloc splitline.c /^void * erealloc(void *p, size_t n)$/;" f
execute execute.c /^int execute(char *argv[])$/;" f
execute shell.c /^int execute(char *arglist[])$/;" f
fatal smsh1.c /^void fatal(char *s1, char *s2, int n)$/;" f
fatal smsh2.c /^void fatal(char *s1, char *s2, int n)$/;" f
fatal smsh4.c /^void fatal(char *s1, char *s2, int n)$/;" f
freelist splitline.c /^freelist(char **list)$/;" f
is_delim splitline.c 55;" d file:
main demon.c /^int main(int argc, const char *argv[])$/;" f
main fork.c /^int main(int argc, const char *argv[])$/;" f
main fork_8.2.c /^int main(int argc, const char *argv[])$/;" f
main fork_8.4.c /^int main(int argc, const char *argv[])$/;" f
main fork_8.5.c /^int main(int argc, const char *argv[])$/;" f
main fork_8.6.c /^int main(int argc, const char *argv[])$/;" f
main pipe.c /^int main(){$/;" f
main shell.c /^int main(int argc, const char *argv[])$/;" f
main smsh1.c /^int main()$/;" f
main smsh2.c /^int main()$/;" f
main smsh4.c /^int main()$/;" f
main sol08.8a.c /^main()$/;" f
main wait_8.8.c /^int main(int argc, const char *argv[])$/;" f
makestring shell.c /^char * makestring(char *buf)$/;" f
newstr splitline.c /^char *newstr(char *s, int l)$/;" f
next_cmd splitline.c /^char * next_cmd(char *prompt, FILE *fp)$/;" f
oops sol08.8a.c 22;" d file:
parent_code sol08.8a.c /^void parent_code(int child1, int child2)$/;" f
parent_code wait_8.8.c /^ void parent_code(pid_t pid1, pid_t pid2){$/;" f
setup smsh1.c /^void setup()$/;" f
setup smsh2.c /^void setup()$/;" f
setup smsh4.c /^void setup()$/;" f
splitline splitline.c /^char ** splitline(char *line)$/;" f
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void child_code(), parent_code(pid_t pid1, pid_t pid2);
int main(int argc, const char *argv[])
{
pid_t pid1, pid2;
if ((pid1 = fork()) == -1) {
perror("fork error\n");
exit(1);
}
if (pid1 == 0) {
child_code();
}
if ((pid2 = fork()) == -1) {
perror("fork error\n");
exit(1);
}
if (pid2 == 0) {
child_code();
}
parent_code(pid1, pid2);
return 0;
}
void child_code(){
printf("this is child ,pid is %d\n", getpid() );
sleep(3);
printf("child done exit\n");
exit(17);
}
void parent_code(pid_t pid1, pid_t pid2){
pid_t wait_rv;
int status;
wait_rv = wait(&status);
printf("wait return is %d, exit value is %d\n", wait_rv, status>>8 );
wait_rv = wait(&status);
printf("wait return is %d, exit value is %d\n", wait_rv, status>>8);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment