Windows上的Unix模擬器Cygwin Run in the Windows(Simulation of UNIX)
Preface
Environment
Cygwin Run in the Windows(Simulation of UNIX)
Resource
Cygwin Install:http://cygwin.com/install.html
Cygwin API:http://cygwin.com/cygwin-api/
Lab 1 Program Layout
Content
Ex. 2.3 P.25
Exercise 2.3
Use ls -l to compare the sizes of the executable modules for the following two C programs. Explain the results.
Version 1: largearrayinit.c
Version 2: largearray.c
Source
Version 1: largearrayinit.c
#include<stdio.h> int myarray[50000] = {1, 2, 3, 4}; int main(void) { myarray[0] = 3; printf("myarray[0]=%d myarray[1]=%d myarray[2]=%d myarray[3]=%d",myarray[0],myarray[1],myarray[2],myarray[3]); return 0; }
Version 2: largearray.c
#include<stdio.h> int myarray[50000]; int main(void) { myarray[0] = 3; printf("myarray[0]=%d myarray[1]=%d myarray[2]=%d",myarray[0],myarray[1],myarray[2]); return 0; }
Result
Version 1: largearrayinit.c
Version 2: largearray.c
Lab2 Argument array
Content
Program 2.1 and 2.2, p.34-37
Program 2.2 makeargv.c
An implementation of makeargv.
Program 2.1 argtest.c
A program that takes a single string as its command-line argument and calls makeargv to create an argument array.
Source
Program 2.2 makeargv.c
#include <errno.h> #include <stdlib.h> #include <string.h> int makeargv(const char *s, const char *delimiters, char ***argvp) { int error; int i; int numtokens; const char *snew; char *t; if ((s == NULL) || (delimiters == NULL) || (argvp == NULL)) { errno = EINVAL; return -1; } *argvp = NULL; snew = s + strspn(s, delimiters); /* snew is real start of string */ if ((t = malloc(strlen(snew) + 1)) == NULL) return -1; strcpy(t, snew); numtokens = 0; if (strtok(t, delimiters) != NULL) /* count the number of tokens in s */ for (numtokens = 1; strtok(NULL, delimiters) != NULL; numtokens++) ; /* create argument array for ptrs to the tokens */ if ((*argvp = malloc((numtokens + 1)*sizeof(char *))) == NULL) { error = errno; free(t); errno = error; return -1; } /* insert pointers to tokens into the argument array */ if (numtokens == 0) free(t); else { strcpy(t, snew); **argvp = strtok(t, delimiters); for (i = 1; i < numtokens; i++) *((*argvp) + i) = strtok(NULL, delimiters); } *((*argvp) + numtokens) = NULL; /* put in final NULL pointer */ return numtokens; }
Program 2.1 argtest.c
#include <stdio.h> #include <stdlib.h> int makeargv(const char *s, const char *delimiters, char ***argvp); int main(int argc, char *argv[]) { char delim[] = " \t"; int i; char **myargv; int numtokens; if (argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); return 1; } if ((numtokens = makeargv(argv[1], delim, &myargv)) == -1) { fprintf(stderr, "Failed to construct an argument array for %s\n", argv[1]); return 1; } printf("The argument array contains:\n"); for (i = 0; i < numtokens; i++) printf("%d:%s\n", i, myargv[i]); return 0; }
Result
Lab3 env
Content
Example 2.22, p.49
Example 2.24, p.51
Example 2.22 environ.c
The following C program outputs the contents of its environment list and exits.
Exercise 2.24 getpaths.c
Write a function to produce an argument array containing the components of the PATH environment variable.
Source
Example 2.22 environ.c
#include <stdio.h> extern char **environ; int main(void) { int i; printf("The environment list follows:\n"); for(i = 0; environ[i] != NULL; i++) printf("environ[%d]: %s\n", i, environ[i]); return 0; }
Exercise 2.24 getpaths.c
#include <stdlib.h> #define PATH_DELIMITERS ":" int makeargv(const char *s, const char *delimiters, char ***argvp); char **getpaths(void) { char **myargv; char *path; path = getenv("PATH"); if (makeargv(path, PATH_DELIMITERS, &myargv) == -1) return NULL; else return myargv; }
getpathstest.c
#include <stdio.h> char **getpaths(void); int main(void) { char **paths; int i; paths = getpaths(); if (paths == NULL) { fprintf(stderr,"No path variable\n"); return 1; } for (i = 0; paths[i] != NULL; i++) printf("[%d]:%s\n", i, paths[i]); return 0; }
Result
Example 2.22 environ.c
Exercise 2.24 getpaths.c
Lab 4 Process Chain and Fan
Content
Program 3.1 and 3.2, p.67, 68
Program 3.1 simplechain.c
A program that creates a chain of n processes, where n is a command-line argument.
Program 3.2 simplefan.c
A program that creates a fan of n processes where n is passed as a command-line argument.
Source
Program 3.1 simplechain.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main (int argc, char *argv[]) { pid_t childpid = 0; int i, n; if (argc != 2){ /* check for valid number of command-line arguments */ fprintf(stderr, "Usage: %s processes\n", argv[0]); return 1; } n = atoi(argv[1]); for (i = 1; i < n; i++) if (childpid = fork()) break; fprintf(stderr, "i:%d process ID:%ld parent ID:%ld child ID:%ld\n", i, (long)getpid(), (long)getppid(), (long)childpid); return 0; }
Program 3.2 simplefan.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main (int argc, char *argv[]) { pid_t childpid = 0; int i, n; if (argc != 2){ /* check for valid number of command-line arguments */ fprintf(stderr, "Usage: %s processes\n", argv[0]); return 1; } n = atoi(argv[1]); for (i = 1; i < n; i++) if ((childpid = fork()) <= 0) break; fprintf(stderr, "i:%d process ID:%ld parent ID:%ld child ID:%ld\n", i, (long)getpid(), (long)getppid(), (long)childpid); return 0; }
Result
Program 3.1 simplechain.c
Program 3.2 simplefan.c
Lab 5 wait()
Content
Ex. 3.21, p.76
Exercise 3.21 chainwaitmsg.c
The following program creates a process chain. Only one forked process is a child of the original process.
Source
Exercise 3.21 chainwaitmsg.c
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main (int argc, char *argv[]) { pid_t childpid; int i, n; pid_t waitreturn; if (argc != 2){ /* check number of command-line arguments */ fprintf(stderr, "Usage: %s processes\n", argv[0]); return 1; } n = atoi(argv[1]); for (i = 1; i < n; i++) if (childpid = fork()) break; while(childpid != (waitreturn = wait(NULL))) if ((waitreturn == -1) && (errno != EINTR)) break; fprintf(stderr, "I am process %ld, my parent is %ld\n", (long)getpid(), (long)getppid()); return 0; }
Result
Exercise 3.21 chainwaitmsg.c
Lab 6 exec()
Content
Program 3.5, p.81
Program 3.5 execcmd.c
A program that creates a child process to execute a command. The command to be executed is passed on the command line.
Source
r_wait.c
#include <errno.h> #include <sys/wait.h> pid_t r_wait(int *stat_loc) { int retval; while (((retval = wait(stat_loc)) == -1) && (errno == EINTR)) ; return retval; }
Program 3.5 execcmd.c
#include <errno.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include "restart.h" int main(int argc, char *argv[]) { pid_t childpid; if (argc < 2){ /* check for valid number of command-line arguments */ fprintf (stderr, "Usage: %s command arg1 arg2 ...\n", argv[0]); return 1; } childpid = fork(); if (childpid == -1) { perror("Failed to fork"); return 1; } if (childpid == 0) { /* child code */ execvp(argv[1], &argv[1]); perror("Child failed to execvp the command"