00001 /* 00002 Miscellaneous examples for Chap. 5 00003 AUP2, Chap. 5 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 #include "defs.h" 00022 00023 /*[exec_path]*/ 00024 int exec_path(const char *path, char *const argv[], char *newargv[]) 00025 { 00026 int i; 00027 00028 execv(path, argv); 00029 if (errno == ENOEXEC) { 00030 newargv[0] = argv[0]; 00031 newargv[1] = (char *)path; 00032 i = 1; 00033 do { 00034 newargv[i + 1] = argv[i]; 00035 } while (argv[i++] != NULL); 00036 return execv("/bin/sh", (char *const *)newargv); 00037 } 00038 return -1; 00039 } 00040 /*[execvp2]*/ 00041 int execvp2(const char *file, char *const argv[]) 00042 { 00043 char *s, *pathseq = NULL, *path = NULL, **newargv = NULL; 00044 int argc; 00045 00046 for (argc = 0; argv[argc] != NULL; argc++) 00047 ; 00048 /* If shell script, we'll need room for one additional arg and NULL. */ 00049 ec_null( newargv = malloc((argc + 2) * sizeof(char *)) ) 00050 s = getenv("PATH"); 00051 if (strchr(file, '/') != NULL || s == NULL || s[0] == '\0') 00052 ec_neg1( exec_path(file, argv, newargv) ) 00053 ec_null( pathseq = strdup(s) ) 00054 /* Following line usually allocates too much */ 00055 ec_null( path = malloc(strlen(file) + strlen(pathseq) + 2) ) 00056 while ((s = strtok(pathseq, ":")) != NULL) { 00057 pathseq = NULL; /* tell strtok to keep going */ 00058 if (s[0] == '\0') 00059 s = "."; 00060 strcpy(path, s); 00061 strcat(path, "/"); 00062 strcat(path, file); 00063 exec_path(path, argv, newargv); 00064 } 00065 errno = ENOENT; 00066 EC_FAIL 00067 00068 EC_CLEANUP_BGN 00069 free(pathseq); 00070 free(path); 00071 free(newargv); 00072 return -1; 00073 EC_CLEANUP_END 00074 } 00075 /*[]*/ 00076 00077 /*[exectest]*/ 00078 void exectest(void) 00079 { 00080 printf("The quick brown fox jumped over "); 00081 ec_neg1( execl("/bin/echo", "echo", "the", "lazy", "dogs.", NULL) ) 00082 return; 00083 00084 EC_CLEANUP_BGN 00085 EC_FLUSH("exectest"); 00086 EC_CLEANUP_END 00087 } 00088 /*[]*/ 00089 /*[forkbuf]*/ 00090 void forkbuf(void) 00091 { 00092 printf("Hello World!\n"); 00093 ec_neg1(fork()); 00094 exit(EXIT_SUCCESS); 00095 return; 00096 00097 EC_CLEANUP_BGN 00098 exit(EXIT_FAILURE); 00099 EC_CLEANUP_END 00100 } 00101 /*[]*/ 00102 00103 void junk(void) 00104 { 00105 int fd, flags; 00106 long open_max; 00107 char *path = "/bin/echo", *arg0 = "hello", *arg1 = "gillian", 00108 *arg2 = " and claire"; 00109 00110 /*[close-before-exec]*/ 00111 errno = 0; 00112 ec_neg1( open_max = sysconf(_SC_OPEN_MAX) ) 00113 printf("open_max = %ld\n", open_max); 00114 for (fd = 0; fd < open_max - 1; fd++) 00115 (void)close(fd); /* ignore errors */ 00116 ec_neg1( execl(path, arg0, arg1, arg2, NULL) ) 00117 /*[close-on-exec]*/ 00118 for (fd = 0; fd < open_max - 1; fd++) { 00119 ec_neg1( flags = fcntl(fd, F_SETFD) ) 00120 ec_neg1( fcntl(fd, F_SETFD, flags | FD_CLOEXEC) ) 00121 } 00122 ec_neg1( execl(path, arg0, arg1, arg2, NULL) ) 00123 /*[]*/ 00124 return; 00125 00126 EC_CLEANUP_BGN 00127 EC_FLUSH("junk"); 00128 EC_CLEANUP_END 00129 } 00130 00131 /*[forktest]*/ 00132 void forktest(void) 00133 { 00134 int pid; 00135 00136 printf("Start of test\n"); 00137 pid = fork(); 00138 printf("Returned %d\n", pid); 00139 } 00140 /*[]*/ 00141 00142 void gp(void) 00143 { 00144 /*5-23*/ 00145 char file[10]; 00146 int tempfd; 00147 00148 sprintf(file, "TMP%ld", (long)getpid()); 00149 if ((tempfd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) 00150 syserr("open"); 00151 /**/ 00152 } 00153 00154 int main(int argc, char *argv[]) 00155 { 00156 forktest(); 00157 //junk(); 00158 //exectest(); 00159 /* 00160 00161 00162 if (argc < 2) { 00163 fprintf(stderr, "Usage: x5a <cmd> [ <arg> ... ]\n"); 00164 exit(EXIT_FAILURE); 00165 } 00166 execvp2(argv[1], &argv[1]); 00167 EC_FAIL 00168 //gp(); 00169 */ 00170 exit(EXIT_SUCCESS); 00171 00172 EC_CLEANUP_BGN 00173 exit(EXIT_FAILURE); 00174 EC_CLEANUP_END 00175 }