00001 /* 00002 editor front-end (unidirectional pipes) 00003 AUP2, Sec. 6.05 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 /* 00022 Sec. 00023 */ 00024 #include "defs.h" 00025 00026 /*[edinvoke]*/ 00027 static FILE *sndfp, *rcvfp; 00028 00029 static bool edinvoke(void) 00030 { 00031 int pfdout[2], pfdin[2]; 00032 pid_t pid; 00033 00034 ec_neg1( pipe(pfdout) ) 00035 ec_neg1( pipe(pfdin) ) 00036 switch (pid = fork()) { 00037 case -1: 00038 EC_FAIL 00039 case 0: 00040 ec_neg1( dup2(pfdout[0], STDIN_FILENO) ) 00041 ec_neg1( dup2(pfdin[1], STDOUT_FILENO) ) 00042 ec_neg1( close(pfdout[0]) ) 00043 ec_neg1( close(pfdout[1]) ) 00044 ec_neg1( close(pfdin[0]) ) 00045 ec_neg1( close(pfdin[1]) ) 00046 execlp("ed", "ed", "-", NULL); 00047 EC_FAIL 00048 } 00049 ec_neg1( close(pfdout[0]) ) 00050 ec_neg1( close(pfdin[1]) ) 00051 ec_null( sndfp = fdopen(pfdout[1], "w") ) 00052 ec_null( rcvfp = fdopen(pfdin[0], "r") ) 00053 return true; 00054 00055 EC_CLEANUP_BGN 00056 if (pid == 0) { 00057 EC_FLUSH("edinvoke"); 00058 _exit(EXIT_FAILURE); 00059 } 00060 return false; 00061 EC_CLEANUP_END 00062 } 00063 /*[edsnd]*/ 00064 static bool edsnd(const char *s) 00065 { 00066 ec_eof( fputs(s, sndfp) ) 00067 return true; 00068 00069 EC_CLEANUP_BGN 00070 return false; 00071 EC_CLEANUP_END 00072 } 00073 00074 static bool edrcv(char *s, size_t smax) 00075 { 00076 ec_null( fgets(s, smax, rcvfp) ) 00077 return true; 00078 00079 EC_CLEANUP_BGN 00080 return false; 00081 EC_CLEANUP_END 00082 } 00083 00084 static bool turnaround(void) 00085 { 00086 ec_false( edsnd("r end-of-file\n") ) 00087 ec_eof( fflush(sndfp) ) 00088 return true; 00089 00090 EC_CLEANUP_BGN 00091 return false; 00092 EC_CLEANUP_END 00093 } 00094 /*[rcvall]*/ 00095 static bool rcvall(void) 00096 { 00097 char s[200]; 00098 00099 ec_false( turnaround() ) 00100 while (true) { 00101 ec_false( edrcv(s, sizeof(s)) ) 00102 if (strcmp(s, "?end-of-file\n") == 0) 00103 break; 00104 printf("%s", s); 00105 } 00106 return true; 00107 00108 EC_CLEANUP_BGN 00109 return false; 00110 EC_CLEANUP_END 00111 } 00112 /*[prompt]*/ 00113 static bool prompt(const char *msg, char *result, size_t resultmax, 00114 bool *eofp) 00115 { 00116 char *p; 00117 00118 printf("\n%s? ", msg); 00119 if (fgets(result, resultmax, stdin) == NULL) { 00120 if (ferror(stdin)) 00121 EC_FAIL 00122 *eofp = true; 00123 } 00124 else { 00125 if ((p = strrchr(result, '\n')) != NULL) 00126 *p = '\0'; 00127 *eofp = false; 00128 } 00129 return true; 00130 00131 EC_CLEANUP_BGN 00132 return false; 00133 EC_CLEANUP_END 00134 } 00135 /*[main]*/ 00136 int main(void) 00137 { 00138 char s[100], line[200]; 00139 bool eof; 00140 00141 ec_false( prompt("File", s, sizeof(s), &eof) ) 00142 if (eof) 00143 exit(EXIT_SUCCESS); 00144 ec_false( edinvoke() ) 00145 snprintf(line, sizeof(line), "e %s\n", s); 00146 ec_false( edsnd(line) ) 00147 ec_false( rcvall() ); 00148 while (true) { 00149 ec_false( prompt("Search pattern", s, sizeof(s), &eof) ) 00150 if (eof) 00151 break; 00152 snprintf(line, sizeof(line), "g/%s/p\n", s); 00153 ec_false( edsnd(line) ) 00154 ec_false( rcvall() ); 00155 } 00156 ec_false( edsnd("q\n") ) 00157 exit(EXIT_SUCCESS); 00158 00159 EC_CLEANUP_BGN 00160 exit(EXIT_FAILURE); 00161 EC_CLEANUP_END 00162 } 00163 /*[]*/ 00164