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