Annotation of OpenXM/src/kan96xx/plugin/file2.c, Revision 1.16
1.16 ! takayama 1: /*$OpenXM: OpenXM/src/kan96xx/plugin/file2.c,v 1.15 2015/10/10 11:29:46 takayama Exp $ */
1.1 maekawa 2: #include <stdio.h>
1.13 ohara 3: #include <string.h>
1.1 maekawa 4: #include <sys/time.h>
5: #include <sys/types.h>
6: #include <unistd.h>
1.12 takayama 7: #include <signal.h>
1.10 takayama 8: #include <errno.h>
1.15 takayama 9: #include <stdlib.h>
1.1 maekawa 10: #include "file2.h"
1.16 ! takayama 11: #include "mysig.h"
1.1 maekawa 12:
1.7 takayama 13: /* If you use file2 standalone to output string,
14: make the following dummy definition;
15: int KsocketSelect0(int a,int b) { return(0); }
16: int oxSocketSelect0(int a,int b) { return(0); }
17: or define FORSTRING
18: */
19: #ifdef FORSTRING
20: #define KsocketSelect0(a,b) 0
21: #define oxSocketSelect0(a,b) 0
22: #endif
23:
1.1 maekawa 24: #ifdef KXX
1.9 takayama 25: #define sGC_malloc(n) malloc(n)
1.1 maekawa 26: #else
1.9 takayama 27: void *sGC_malloc(int size);
1.1 maekawa 28: #endif
1.2 takayama 29: int WatchStream = 0;
1.1 maekawa 30: /* Note: 1997, 12/6 cf. SS475/kxx/openxxx.tex, SS475/memo1.txt
31: The functions in file2.c should not accept interruptions
32: during its critical operations. The synchronization mechanism
33: has not yet been implemented.
34: */
35:
36: static int debug1 = 0;
37: static int checkfp2(FILE2 *fp2,char *s);
1.7 takayama 38: static int fp2fputcString(int c,FILE2 *fp2);
1.1 maekawa 39: static int checkfp2(FILE2 *fp2,char *s)
40: {
41: if (fp2 == NULL) {
42: fprintf(stderr,"%s: NULL pointer.\n",s);
43: return(-1);
44: }
45: if (fp2->initialized != 1) {
46: fprintf(stderr,"%s: fp is not initialized.\n",s);
47: return(-1);
48: }
49: return(0);
50: }
51:
52: FILE2 *fp2open(int fd) {
53: FILE2 *fp2;
54: if (debug1) {
55: printf("fp2open is called. \n");
56: }
1.9 takayama 57: fp2 = (FILE2 *) sGC_malloc(sizeof(FILE2));
1.7 takayama 58: if (fd < -1) {
1.1 maekawa 59: fprintf(stderr,"fp2open Invalid file descriptor %d\n",fd);
60: return(NULL);
61: }
1.7 takayama 62: /* fd == -1 ==> store in string. */
1.1 maekawa 63: if (fp2 == NULL) {
64: fprintf(stderr,"fp2open. No memory.\n");
65: return(NULL);
66: }
67: fp2->fd = fd;
68: fp2->initialized = 1;
69: checkfp2(fp2,"fp2open ");
70: fp2->readpos = 0;
71: fp2->readsize = 0;
72: fp2->writepos = 0;
73: fp2->limit = FILE2BSIZE;
1.9 takayama 74: fp2->readBuf = (char *) sGC_malloc(FILE2BSIZE);
75: fp2->writeBuf = (char *) sGC_malloc(FILE2BSIZE);
1.7 takayama 76: if ((fp2->readBuf == NULL) || (fp2->writeBuf == NULL)) {
77: fprintf(stderr,"fp2open. No more memory.\n");
78: return(NULL);
79: }
1.1 maekawa 80: fp2->watch = 0;
81: fp2->watchFile = NULL;
82: fp2->mathcapList = NULL;
1.5 takayama 83: fp2->log_incomming = NULL;
84: fp2->log_outgoing = NULL;
1.11 takayama 85: fp2->popened = 0;
86: fp2->pfp = NULL;
1.1 maekawa 87: return(fp2);
88: }
89:
1.11 takayama 90: void fp2setfp(FILE2 *fp2,FILE *fp,int popened) {
91: fp2->pfp = fp;
92: fp2->popened = popened;
93: }
1.1 maekawa 94:
95: int fp2fflush(FILE2 *fp2) {
96: int r;
97: if (debug1) {
98: printf("fp2fflush is called with FILE2 *%x.\n", (int )fp2);
99: fp2dumpBuffer(fp2);
100: printf("--------------------------\n");
101: }
102: if (checkfp2(fp2,"fp2fflush ") == -1) return(-1);
1.7 takayama 103: if (fp2->fd == -1) return(0);
1.1 maekawa 104: if (fp2->writepos > 0) {
1.16 ! takayama 105: mysignal(SIGPIPE,SIG_IGN);
1.1 maekawa 106: r = write(fp2->fd,fp2->writeBuf,fp2->writepos);
1.16 ! takayama 107: mysignal(SIGPIPE,SIG_DFL);
1.1 maekawa 108: fp2->writepos = 0;
109: if (r <= 0) {
110: fprintf(stderr,"fp2fflush(): write failed on %d.\n",fp2->fd);
1.12 takayama 111: if (errno == EPIPE) {
112: fprintf(stderr,"Your peer is closed --- SIGPIPE. Closing this fp2.\n");
113: fp2fclose(fp2);
114: return r;
115: }
1.1 maekawa 116: }
117: return(r);
118: }else{
119: return(0);
120: }
121: }
122:
123: int fp2fclose(FILE2 *fp2) {
124: int r;
125: if (checkfp2(fp2," fp2fclose ") == -1) return(-1);
1.7 takayama 126: if (fp2->fd == -1) return(0);
1.1 maekawa 127: r = fp2fflush(fp2);
128: if (r < 0) {
129: fprintf(stderr,"fp2fclose: flush error.\n");
130: return(-1);
131: }
1.11 takayama 132: if (fp2->pfp != NULL) {
133: if (fp2->popened) {
134: return pclose(fp2->pfp);
135: } else return fclose(fp2->pfp);
136: }
137: else return(close(fp2->fd));
1.1 maekawa 138: }
139:
140: int fp2fputc(int c,FILE2 *fp2) {
1.2 takayama 141: FILE *fp;
1.1 maekawa 142: if (debug1) {
143: printf("fp2fputc is called with %2x, fp2->writepos=%d, ",c,fp2->writepos);
144: printf("fp2 = %x.\n",(int) fp2);
145: }
1.2 takayama 146: if (fp2->watch || WatchStream) {
1.4 takayama 147: if (fp2->watch) fp = fp2->watchFile;
148: else fp = stderr;
1.6 takayama 149: fprintf(stderr,"put to <%x> ",fp2->fd); /* output the channel for debug */
1.1 maekawa 150: if (c >= ' ' && c <='z') {
1.3 takayama 151: fprintf(fp," %2x(%c)-> ",c& 0xff,c);
1.1 maekawa 152: }else{
1.3 takayama 153: fprintf(fp," %2x( )-> ",c& 0xff);
1.1 maekawa 154: }
155: fflush(NULL);
156: }
1.5 takayama 157: if (fp2->log_outgoing != NULL) fputc(c,fp2->log_outgoing);
1.1 maekawa 158: if (checkfp2(fp2," fp2fputc ") == -1) return(-1);
159: (fp2->writeBuf)[fp2->writepos] = c;
160: (fp2->writepos)++;
1.7 takayama 161: if (fp2->fd == -1) return(fp2fputcString(c,fp2));
1.1 maekawa 162: if (fp2->writepos < fp2->limit) {
163: return(c);
164: }else{
165: if (fp2fflush(fp2) <0) return(-1);
166: else return(c);
167: }
168: }
169:
170: int fp2fgetc(FILE2 *fp2) {
171: int c;
1.2 takayama 172: FILE *fp;
1.1 maekawa 173: /* printf("fp2fgetc is called. "); fflush(NULL); */
174: if (checkfp2(fp2," fp2fgetc ") == -1) return(-1);
175: if (fp2->readpos < fp2->readsize) {
176: fp2->readpos++;
177: c = fp2->readBuf[fp2->readpos -1];
1.2 takayama 178: if (fp2->watch || WatchStream) {
1.4 takayama 179: if (fp2->watch) fp = fp2->watchFile;
180: else fp = stderr;
1.6 takayama 181: fprintf(fp,"get from <%x> ",fp2->fd); /* output the channel for debug*/
1.1 maekawa 182: if (c >= ' ' && c <= 'z') {
1.4 takayama 183: fprintf(fp," %2x(%c) ",c,c);
1.1 maekawa 184: }else{
1.4 takayama 185: fprintf(fp," %2x( ) ",c);
1.1 maekawa 186: }
187: fflush(NULL);
188: }
1.5 takayama 189: if (fp2->log_incomming != NULL) fputc(c,fp2->log_incomming);
1.1 maekawa 190: return(c);
191: }else{
1.7 takayama 192: if (fp2->fd == -1) return(-1);
1.1 maekawa 193: fp2->readpos = 0;
194: fp2 ->readsize =
195: read(fp2->fd, fp2->readBuf, fp2->limit);
196: if (fp2->readsize == 0) {
1.2 takayama 197: if (fp2->watch || WatchStream) {
1.4 takayama 198: if (fp2->watch) fp = fp2->watchFile;
199: else fp = stderr;
200: fprintf(fp," <%2x ",c);
201: fflush(NULL);
1.1 maekawa 202: }
203: return(-1);
204: }
205: else {
206: return(fp2fgetc(fp2));
207: }
208: }
209: }
210:
211: int fp2select(FILE2 *fp2, int t) {
1.7 takayama 212: if (fp2->fd == -1) {
213: if (fp2->readpos < fp2->readsize) return(1);
214: else return(0);
215: }
1.1 maekawa 216: if (fp2->readpos < fp2->readsize) return(1);
217: else {
218: #ifdef KXX
219: return(oxSocketSelect0(fp2->fd,t));
220: #else
221: return(KsocketSelect0(fp2->fd,t));
222: #endif
223: }
224: }
225:
226: int fp2dumpBuffer(FILE2 *fp2) {
227: int i;
228: if (checkfp2(fp2," f2pdumpBuf ") == -1) {
229: return(-1);
230: }
231: printf("fd=%d\n",fp2->fd);
232: printf("initialied=%d\n",fp2->initialized);
233: printf("readpos=%d\n",fp2->readpos);
234: printf("readsize=%d\n",fp2->readsize);
235: printf("writepos=%d\n",fp2->writepos);
236: printf("limit=%d\n",fp2->limit);
237: for (i=0; i<fp2->readsize; i++) {
238: printf("readBuf[%d]=%2x ",i,fp2->readBuf[i]);
239: }
240: for (i=0; i<fp2->writepos; i++) {
241: printf("writeBuf[%d]=%2x ",i,fp2->writeBuf[i]);
242: }
243: printf("\n");
244: return(0);
245: }
246:
247: int fp2clearReadBuf(FILE2 *fp2) {
248: fd_set readfds;
249: struct timeval timeout;
250: int fd;
251: #define TMP00SIZE 2000
252: char tmp00[TMP00SIZE];
253: int n;
254:
255: if (checkfp2(fp2," fp2clearReadBuf ") == -1) {
256: return(-1);
257: }
1.7 takayama 258: if (fp2->fd == -1) return(0);
1.1 maekawa 259:
260: fp2->readsize=0; fp2->readpos = 0; /* Clear the buffer. */
261:
262: fd = fp2->fd;
263: while (1) {
264: FD_ZERO(&readfds);
265: FD_SET(fd,&readfds);
266: timeout.tv_sec = 0;
267: timeout.tv_usec = (long) 0;
268: fp2->readpos = fp2->readsize = 0;
269: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
270: fprintf(stderr,"fp2clearReadBuf: Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
271: return(-1);
272: }
273: if (FD_ISSET(fd,&readfds)) {
274: n = read(fd,tmp00, TMP00SIZE);
275: if (n <= 0) {
1.4 takayama 276: fprintf(stderr,"fp2clearReadBuf: File is closed or read error.\n");
277: return(-1);
1.1 maekawa 278: }
279: if ( n < TMP00SIZE ) {
1.4 takayama 280: return(0);
1.1 maekawa 281: }
282: }else {
283: return(0);
284: }
285: }
286: }
287: int fp2write(FILE2 *os, char *data, int size) {
288: int i,r;
289: for (i=0; i<size; i++) {
1.14 takayama 290: r = fp2fputc((unsigned char)(data[i]),os);
1.1 maekawa 291: }
292: return(r);
293: }
294:
295: int fp2watch(FILE2 *fp2,FILE *f)
296: {
297: if (f == NULL) {
298: fprintf(stderr,"fp2watch FILE *f is NULL.\n");
299: return(-1);
300: }
301: if (fp2 == NULL) {
302: fprintf(stderr,"fp2watch FILE2 *fp2 is NULL.\n");
303: return(-1);
304: }
305: if (fp2->watch) {
306: fprintf(stderr,"fp2watch: fp2 is already taking a log.");
307: return(-1);
308: }
309: fp2->watch = 1;
310: fp2->watchFile = f;
311: return(0);
312: }
313:
314: int fp2stopWatch(FILE2 *fp2)
315: {
316: if (fp2 == NULL) {
317: fprintf(stderr,"fp2stopWatch FILE2 *fp2 is NULL.\n");
318: return(-1);
319: }
320: if (!fp2->watch) {
321: fprintf(stderr,"fp2stopWatch: fp2 is not taking a log.");
322: return(-1);
323: }
324: fp2->watch=0;
325: if (fp2->watchFile != stdout) {
326: return(fclose(fp2->watchFile));
327: }
328: }
329:
1.5 takayama 330: int fp2log(FILE2 *fp,FILE *incomming,FILE *outgoing) {
331: fp->log_incomming = incomming;
332: fp->log_outgoing = outgoing;
333: return 0;
334: }
335: int fp2stopLog(FILE2 *fp) {
336: if (fp->log_incomming != NULL) fclose(fp->log_incomming);
337: if (fp->log_outgoing != NULL) fclose(fp->log_outgoing);
338: fp->log_incomming = fp->log_outgoing = NULL;
339: return 0;
340: }
1.7 takayama 341:
342: static int fp2fputcString(int c,FILE2 *fp2) {
343: unsigned char *newwrite,*newread;
344: int newsize;
345: int i;
346: (fp2->readBuf)[fp2->readsize] = c;
347: (fp2->readsize)++;
348: if ((fp2->writepos < fp2->limit) && (fp2->readsize < fp2->limit)) return(c);
349: if ((fp2->limit)*2 >=0x3000000) {
350: fprintf(stderr,"Too big output string.\n");
351: return(-1);
352: }
353: newsize = (fp2->limit)*2;
1.9 takayama 354: newwrite = (char *)sGC_malloc(newsize);
355: newread = (char *)sGC_malloc(newsize);
1.7 takayama 356: if ((newwrite == NULL) || (newread == NULL)) {
357: fprintf(stderr,"fp2fputcString: No more memory.\n");
358: return(-1);
359: }
360: for (i=0; i<fp2->writepos; i++) {
361: newwrite[i] = fp2->writeBuf[i];
362: }
363: for (i=0; i<fp2->readsize; i++) {
364: newread[i] = fp2->readBuf[i];
365: }
366: fp2->writeBuf = newwrite;
367: fp2->readBuf = newread;
368: fp2->limit = newsize;
369: return(c);
370: }
371:
372: char *fp2fcloseInString(FILE2 *fp2, int *sizep)
373: {
374: if (fp2->fd == -1) {
375: fp2fputc(0,fp2);
376: *sizep = fp2->writepos-1;
377: return(fp2->writeBuf);
378: }else{
379: fprintf(stderr,"fp2fcloseInString is called for a file stream that is not associated to a string.\n");
380: }
1.8 takayama 381: }
382:
383: int fp2fputs(char *s,FILE2 *fp) {
384: int i,n;
385: n = strlen(s);
386: for (i=0; i<n; i++) {
1.14 takayama 387: if (fp2fputc((unsigned char)(s[i]),fp) < 0) return(-1);
1.8 takayama 388: }
389: return(0);
1.7 takayama 390: }
391:
392: /* Sample program FORSTRING
393: FILE2 *fp2;
394: int c;
395: char *s;
396: int size;
397: fp2 = fp2fopen(-1);
398: while ((c = getchar()) != EOF) {
399: fp2fputc(c,fp2);
400: }
401: s = fp2fcloseInString(fp2,&size);
402:
403: or
404:
405: while ((c = fp2fgetc(fp2)) != EOF) {
406: ....
407: }
408: */
1.12 takayama 409:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>