reality% num p_addr.c 1 /* p_addr.c 2 This program introduces 3 predefined variables: etext, edata, and end. 3 It illustrates the locations of global, static, local, & function addresses. 4 Also included is the stringization of tokens in C. 5 */ 6 #include 7 #include 8 #define PADDR(x) printf(#x " at %u\n", &x); 9 extern unsigned etext, edata, end; 10 static char es_uch, es_ch = 'S'; 11 int e_uint, e_int = 5; 12 main(int argc, char *argv[]) 13 { 14 void f1(int), f2(float); 15 static float s_uf, s_f = 5.0; 16 int i, j = 5; 17 printf("End of text seqment at %u\n", &etext); 18 printf("End of initialized statics and externals at %u\n", &edata); 19 printf("End of uninitialized statics and externals at %u\n", &end); 20 printf("main() at %u\n", main); 21 printf("f1() at %u\n", f1); 22 printf("f2() at %u\n", f2); 23 PADDR(es_uch); 24 PADDR(es_ch); 25 PADDR(e_uint); 26 PADDR(e_int); 27 PADDR(argc); 28 PADDR(argv); 29 PADDR(i); 30 PADDR(j); 31 PADDR(s_uf); 32 PADDR(s_f); 33 f1(i); 34 f2(s_f); 35 f1(j); 36 return(0); 37 } 38 void f1(int f1_i) 39 { 40 float f1_j, f1_k = 5; 41 int *f1_pi = (int *)malloc(sizeof(int) * 16); 42 char *f1_pc = (char *)malloc(sizeof(char) * 16); 43 PADDR(f1_i); 44 PADDR(f1_j); 45 PADDR(f1_k); 46 PADDR(f1_pi); 47 PADDR(f1_pc); 48 free(f1_pi); 49 free(f1_pc); 50 } 51 void f2(float f2_i) 52 { 53 static int f2_sj, f2_sk = 5; 54 PADDR(f2_i); 55 PADDR(f2_sj); 56 PADDR(f2_sk); 57 f1(5); 58 } reality% p_addr End of text segment at 68757 End of initialized statics and externals at 134600 End of uninitialized statics and externals at 134620 main() at 67416 f1() at 67852 f2() at 68036 es_uch at 134604 es_ch at 134568 e_uint at 134616 e_int at 134572 argc at 4026530780 argv at 4026530784 i at 4026530692 j at 4026530688 s_uf at 134608 s_f at 134576 f1_i at 4026530660 f1_j at 4026530572 f1_k at 4026530568 f1_pi at 4026530564 f1_pc at 4026530560 f2_i at 4026530660 f2_sj at 134600 f2_sk at 134580 f1_i at 4026530548 f1_j at 4026530460 f1_k at 4026530456 f1_pi at 4026530452 f1_pc at 4026530448 f1_i at 4026530660 f1_j at 4026530572 f1_k at 4026530568 f1_pi at 4026530564 f1_pc at 4026530560 reality% num envi.c 1 /* envi.c 2 This programs introduces char **environ and char *envp[]. It also shows 3 how to use getenv() and putenv(). 4 */ 5 #include 6 extern char **environ; 7 main(int argc, char *argv[], char *envp[]) 8 { 9 int i; 10 for (i = 0; argv[i] != NULL; i++) 11 printf("argv[%d] = %s\n", i, argv[i]); 12 printf("\n"); 13 for (i = 0; envp[i] != NULL; i++) 14 printf("envp[%d] = %s\n", i, envp[i]); 15 printf("\n"); 16 for (i = 0; environ[i] != NULL; i++) 17 printf("environ[%d] = %s\n", i, environ[i]); 18 19 printf("\nHOME = %s", getenv("HOME")); 20 putenv("HOME=/users/sam/home"); 21 printf("\nHOME = %s", getenv("HOME")); 22 return(0); 23 } reality% envi argv[0] = envi envp[0] = HOME=/users/sam envp[1] = USER=sam envp[2] = LOGNAME=sam envp[3] = PATH=/bin:/usr/bin:/usr/ucb:/usr/bin/X11:/usr/local/bin:/usr/local/bin:/usr/ccs/bin:/opt/SUNWspro/bin:/home/home6/faculty/sam/bin:. envp[4] = MAIL=/var/mail/sam envp[5] = SHELL=/bin/tcsh envp[6] = TZ=US/Eastern envp[7] = HZ=100 envp[8] = SSH_CLIENT=131.91.80.27 1023 22 envp[9] = SSH_TTY=/dev/pts/5 envp[10] = TERM=xterms environ[0] = HOME=/users/sam environ[1] = USER=sam environ[2] = LOGNAME=sam environ[3] = PATH=/bin:/usr/bin:/usr/ucb:/usr/bin/X11:/usr/local/bin:/usr/local/bin:/usr/ccs/bin:/opt/SUNWspro/bin:/home/home6/faculty/sam/bin:. environ[4] = MAIL=/var/mail/sam environ[5] = SHELL=/bin/tcsh environ[6] = TZ=US/Eastern environ[7] = HZ=100 environ[8] = SSH_CLIENT=131.91.80.27 1023 22 environ[9] = SSH_TTY=/dev/pts/5 environ[10] = TERM=xterms HOME = /users/sam HOME = /users/sam/home reality% num openf.c 1 /* openf.c 2 This program shows examples of using fork(), wait(), and execl() calls. 3 It also shows that an open file is shared among parent/child unless 4 close-on-exec is set. How to retrieve process exit code is illustrated too. 5 */ 6 #include 7 #include 8 #include 9 #include 10 main() 11 { 12 int fdes, pid, cflag, excode; 13 long pos; 14 fdes = open("openf.c", O_RDONLY); /* open its src file */ 15 printf("fdes = %d\n", fdes); /* inspect file descriptor */ 16 pos = lseek(fdes, 20l, SEEK_SET); /* 20 is an arbitrary number */ 17 printf("Current position before fork() is %ld\n", pos); 18 if(!fork()) { /* child */ 19 pos = lseek(fdes, 40l, SEEK_SET); /* 40 is also arbitrary */ 20 printf("Current position in child after fork() is %ld\n", pos); 21 } 22 else { /* parent */ 23 wait((int *)0); /* wait for 1st child to terminate */ 24 pos = lseek(fdes, 0l, SEEK_CUR); /* to get pos in file */ 25 printf("Current position in parent after fork() is %ld\n", pos); 26 if (!fork()) { /* fork again -- child process */ 27 execl("./openfexec", 0); /* overlay with another program */ 28 printf("It is an error to print this line out\n"); 29 } 30 /* parent -- no need for else */ 31 wait(&excode); /* exit code is needed */ 32 pos = lseek(fdes, 0l, SEEK_CUR); 33 printf("Current pos in parent after exec() is %ld\n", pos); 34 printf("Exit code of a child = %d\n", WEXITSTATUS(excode)); 35 cflag = fcntl(fdes, F_GETFD, 0); /* 3rd arg can be any int here */ 36 printf("close-on-exec flag = %d\n", cflag); /* 1 = set */ 37 fcntl(fdes, F_SETFD, 1); /* set close-on-exec flag */ 38 if (pid = fork()) { /* fork again -- parent process */ 39 waitpid(pid, &excode, 0); /* wait for a specific child to end */ 40 printf("Exit code of a specific child = %d\n", WEXITSTATUS(excode)); 41 exit(0); /* parent terminates */ 42 } 43 execl("./openfexec", 0); /* child executes another program */ 44 printf("It is an error to print this line out\n"); 45 } 46 } reality% num openfexec.c 1 /* openfexec.c 2 This program is called by openf to illustrate the sharing of an open file 3 between the parent and child processes. 4 */ 5 #include 6 main() 7 { 8 int fd = 3; /* I know it is 3 */ 9 long pos; 10 pos = lseek(fd, 0l, SEEK_CUR); 11 printf("\tPos in openfexec(): is %ld\n", pos); 12 pos = lseek(fd, 50l, SEEK_CUR); /* an arbitrary no */ 13 printf("\tNew pos after lseek() in openfexec() is %ld\n", pos); 14 exit(pos < 0 ? !0 : 0); /* return non-zero if not OK */ 15 } reality% openf fdes = 3 Current position before fork() is 20 Current position in child after fork() is 40 Current position in parent after fork() is 40 Pos in openfexec(): is 40 New pos after lseek() in openfexec() is 90 Current pos in parent after exec() is 90 Exit code of a child = 0 close-on-exec flag = 0 Pos in openfexec(): is -1 New pos after lseek() in openfexec() is -1 Exit code of a specific child = 1 reality% num forkexec.c 1 /* forkexec.c 2 This program accepts a command from the user and initiates its execution. 3 Also included is the concept of closing the standard input at user layer. 4 */ 5 #include 6 #include 7 #define MAX 100 8 main() 9 { 10 int i = 0; 11 char arg[BUFSIZ], *argbuf[MAX]; 12 printf("\nEnter command (full pathname) to be executed > "); 13 scanf("%s", arg); 14 argbuf[i] = malloc(strlen(arg)+1); /* allocate space to store arg value */ 15 strcpy(argbuf[i++], arg); 16 while (1) { /* to get arguments */ 17 printf("Please enter argument ( to terminate) > "); 18 if (scanf("%s", arg) != EOF) { 19 argbuf[i] = malloc(strlen(arg)+1); /* one extra for null */ 20 strcpy(argbuf[i++], arg); 21 } 22 else 23 break; /* break upon EOF */ 24 } 25 argbuf[i] = (char *)NULL; /* to terminate argv list */ 26 printf("\nWould you like to spawn a child process (y/n) > "); 27 read(0, arg, 1); /* a dirty fix -- was scanf("%s", arg); */ 28 if (arg[0] == 'y') { 29 if (fork()) { /* parent process */ 30 printf("Parent is waiting"); 31 wait((int *)0); /* wait till child terminates */ 32 exit(0); 33 } 34 else { /* child process */ 35 printf("\nChild will be overlaid by %s\n", *argbuf); 36 execv(*argbuf , argbuf); /* execute a new program */ 37 printf("\nSomething is wrong"); 38 } 39 } 40 printf("\nNo forking: %s will overlay current process\n", *argbuf); 41 execv(*argbuf , argbuf); /* execute a new program */ 42 printf("\nThis line shouldn't be here"); 43 } reality% forkexec Enter command (full pathname) to be executed > /bin/pwd Please enter argument ( to terminate) > ^D Would you like to spawn a child process (y/n) > y Child will be overlaid by /bin/pwd /home/home6/faculty/sam/temp Parent is waiting reality% forkexec Enter command (full pathname) to be executed > /bin/echo Please enter argument ( to terminate) > this Please enter argument ( to terminate) > is Please enter argument ( to terminate) > echo Please enter argument ( to terminate) > ^D Would you like to spawn a child process (y/n) > n No forking: /bin/echo will overlay current process this is echo reality% num times.c 1 /* times.c 2 This program shows how to get the real time (wall clock time), and CPU times 3 of a process. 4 gettimeofday() is used to get the time of day, measured in sec & micro sec, 5 counting from 00:00:00 Jan 1, 1970, GMT. 6 It also introduces the structures of rusage and timeval, and wait4() 7 */ 8 #include 9 #include 10 #include 11 #include 12 #include 13 #define MICRO 1000000 14 main() 15 { 16 int i, pid, statusp, option = 0; 17 struct rusage rusag; 18 long start, end, walltime; 19 struct timeval tm_beg, tm_end; 20 gettimeofday(&tm_beg, (struct timezone *)0); /* what time is it? */ 21 start = tm_beg.tv_sec * MICRO; /* convert to micro seconds */ 22 start += tm_beg.tv_usec; 23 if (pid = fork()) { 24 wait4(pid, &statusp, option, &rusag); 25 gettimeofday(&tm_end, (struct timezone *)0); /* what time is it? */ 26 end = tm_end.tv_sec * MICRO; /* convert to micro seconds */ 27 end += tm_end.tv_usec; 28 printf("PARENT\n"); 29 printf("systime = %ld, ", rusag.ru_stime.tv_usec + 30 rusag.ru_stime.tv_sec * MICRO); /* in usec */ 31 printf("usertime= %ld, ", rusag.ru_utime.tv_usec + 32 rusag.ru_utime.tv_sec * MICRO); /* in usec */ 33 printf("walltime = %ld\n", end - start); /* in usec */ 34 } 35 else { 36 printf("CHILD\n"); 37 for (i = 0; i < MICRO; i++); /* to get some delay */ 38 } 39 return(0); 40 } reality% times CHILD PARENT systime = 10000, usertime= 160000, walltime = 180062 reality% num mystrtok.c 1 #include 2 #include 3 char str1[] = "This:is:a:try:hi:sam"; 4 char str2[] = ":"; 5 char *p; 6 main() 7 { 8 int i, size = 0; 9 printf("tok = %s\n", strtok(str1, str2)); 10 for (i = 0; i < 5; i++) { 11 printf("tok = %s \n", strtok(NULL, str2)); 12 } 13 } reality% mystrtok tok = This tok = is tok = a tok = try tok = hi tok = sam