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