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