1. 程式人生 > >Windows上的Unix模擬器Cygwin Run in the Windows(Simulation of UNIX)

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"