00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "file_modes_xsb.h"
00031
00032 #if (defined(CYGWIN))
00033 #include <fcntl.h>
00034 #endif
00035
00036 #ifdef WIN_NT
00037 #include <io.h>
00038 #endif
00039
00040
00041 STRFILE *iostrs[MAXIOSTRS] = {NULL,NULL,NULL,NULL,NULL};
00042
00043 extern char *expand_filename(char *filename);
00044 extern int xsb_intern_fileptr(FILE *, char *, char *, char *);
00045
00046 static FILE *stropen(char *str)
00047 {
00048 int i, len;
00049 STRFILE *tmp;
00050 char *stringbuff;
00051
00052 for (i=0; i<MAXIOSTRS; i++) {
00053 if (iostrs[i] == NULL) break;
00054 }
00055 if (i>=MAXIOSTRS) return FALSE;
00056 tmp = (STRFILE *)mem_alloc(sizeof(STRFILE),OTHER_SPACE);
00057 iostrs[i] = tmp;
00058 len = strlen(str);
00059
00060 stringbuff = (char *)mem_alloc(len+1,OTHER_SPACE);
00061 strcpy(stringbuff,str);
00062
00063 tmp->strcnt = len;
00064 tmp->strptr = stringbuff;
00065 tmp->strbase = stringbuff;
00066 return (FILE *)iostrdecode(i);
00067 }
00068
00069 static void strclose(int i)
00070 {
00071 i = iostrdecode(i);
00072 if (iostrs[i] != NULL) {
00073 mem_dealloc(iostrs[i]->strbase,iostrs[i]->strcnt+1,OTHER_SPACE);
00074 mem_dealloc((byte *)iostrs[i],sizeof(STRFILE),OTHER_SPACE);
00075 iostrs[i] = NULL;
00076 }
00077 }
00078
00079 #ifdef MULTI_THREAD
00080 #define XSB_STREAM_LOCK(index) { \
00081 if (index >= 0) pthread_mutex_lock(OPENFILES_MUTEX(index)); \
00082 else pthread_mutex_lock(OPENFILES_MUTEX(iostrdecode(index))); \
00083 }
00084 #define XSB_STREAM_UNLOCK(index) { \
00085 if (index >= 0) pthread_mutex_unlock(OPENFILES_MUTEX(index)); \
00086 else pthread_mutex_unlock(OPENFILES_MUTEX(iostrdecode(index))); \
00087 }
00088 #else
00089 #define XSB_STREAM_LOCK(index)
00090 #define XSB_STREAM_UNLOCK(index)
00091 #endif
00092
00093
00094
00095
00096
00097 #define STDIN 0
00098 #define STDOUT 1
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 inline static xsbBool file_function(CTXTdecl)
00110 {
00111 FILE *fptr;
00112 int io_port, value, size, offset, length, mode;
00113 STRFILE *sfptr;
00114 XSB_StrDefine(VarBuf);
00115 char *addr, *tmpstr;
00116 prolog_term pterm;
00117 Cell term;
00118 char *strmode;
00119
00120 switch (ptoc_int(CTXTc 1)) {
00121 case FILE_FLUSH:
00122
00123 io_port = ptoc_int(CTXTc 2);
00124 XSB_STREAM_LOCK(io_port);
00125 SET_FILEPTR(fptr, io_port);
00126 value = fflush(fptr);
00127 XSB_STREAM_UNLOCK(io_port);
00128 ctop_int(CTXTc 3, (int) value);
00129 break;
00130 case FILE_SEEK:
00131 io_port = ptoc_int(CTXTc 2);
00132 if (io_port < 0) {
00133 if (ptoc_int(CTXTc 4) != 0)
00134 xsb_permission_error(CTXTc "file_seek","atom",ptoc_int(CTXTc 4),"file_seek",1);
00135 XSB_STREAM_LOCK(io_port);
00136 sfptr = iostrs[iostrdecode(io_port)];
00137 value = ptoc_int(CTXTc 3);
00138 length = sfptr->strcnt + sfptr->strptr - sfptr->strbase ;
00139 if (value <= length) {
00140 if (sfptr->strcnt == -1) length++;
00141 sfptr->strptr = sfptr->strbase + value;
00142 sfptr->strcnt = length - value;
00143 ctop_int(CTXTc 5, 0);
00144 }
00145 else ctop_int(CTXTc 5,-1);
00146 XSB_STREAM_UNLOCK(io_port);
00147 }
00148 else {
00149 XSB_STREAM_LOCK(io_port);
00150 SET_FILEPTR(fptr, io_port);
00151 value = fseek(fptr, (long) ptoc_int(CTXTc 3), ptoc_int(CTXTc 4));
00152 XSB_STREAM_UNLOCK(io_port);
00153 ctop_int(CTXTc 5, (int) value);
00154 }
00155 break;
00156 case FILE_TRUNCATE:
00157 size = ptoc_int(CTXTc 3);
00158 io_port = ptoc_int(CTXTc 2);
00159 XSB_STREAM_LOCK(io_port);
00160 SET_FILEPTR(fptr, io_port);
00161 #ifndef WIN_NT
00162 fseek(fptr, (long) size, 0);
00163 value = ftruncate( fileno(fptr), (off_t) size);
00164 ctop_int(CTXTc 4, (int) value);
00165 #else
00166 ctop_int(CTXTc 4, (int) _chsize(fileno(fptr), size));
00167 #endif
00168 XSB_STREAM_UNLOCK(io_port);
00169 break;
00170 case FILE_POS:
00171 io_port = ptoc_int(CTXTc 2);
00172 term = ptoc_tag(CTXTc 3);
00173 if (io_port >= 0) {
00174 XSB_STREAM_LOCK(io_port);
00175 SET_FILEPTR(fptr, io_port);
00176 if (isnonvar(term)) {
00177 XSB_STREAM_UNLOCK(io_port);
00178 return ptoc_int(CTXTc 3) == ftell(fptr);
00179 }
00180 else
00181 ctop_int(CTXTc 3, ftell(fptr));
00182 } else {
00183 XSB_STREAM_LOCK(io_port);
00184 sfptr = strfileptr(io_port);
00185 if (sfptr->strcnt == EOF)
00186 offset = EOF;
00187 else
00188 offset = sfptr->strptr - sfptr->strbase;
00189 if (isnonvar(term)) {
00190 XSB_STREAM_UNLOCK(io_port);
00191 return ptoc_int(CTXTc 3) == offset;
00192 }
00193 else
00194 ctop_int(CTXTc 3, offset);
00195 }
00196 XSB_STREAM_UNLOCK(io_port);
00197 break;
00198 case XSB_FILE_OPEN: {
00199
00200
00201
00202 int ioport, opennew;
00203 int str_type = 0;
00204 char string_mode[3];
00205
00206 tmpstr = ptoc_longstring(CTXTc 2);
00207 pterm = reg_term(CTXTc 3);
00208
00209 SYS_MUTEX_LOCK( MUTEX_IO );
00210
00211 if (isstring(pterm)) {
00212 strcpy(string_mode,string_val(pterm));
00213
00214 switch ((string_mode)[0]) {
00215 case 'r':
00216 mode = OREAD;
00217 if ((string_mode)[1] == 'b')
00218 str_type = BINARY_FILE_STREAM;
00219 else str_type = TEXT_FILE_STREAM;
00220 break;
00221 case 'w':
00222 mode = OWRITE;
00223 if ((string_mode)[1] == 'b')
00224 str_type = BINARY_FILE_STREAM;
00225 else str_type = TEXT_FILE_STREAM;
00226 break;
00227 case 'a':
00228 mode = OAPPEND;
00229 if ((string_mode)[1] == 'b')
00230 str_type = BINARY_FILE_STREAM;
00231 else str_type = TEXT_FILE_STREAM;
00232 break;
00233 case 's':
00234 str_type = STRING_STREAM;
00235 if ((string_mode)[1] == 'r')
00236
00237 mode = OSTRINGR;
00238 else if ((string_mode)[1] == 'w')
00239
00240 mode = OSTRINGW;
00241 else
00242 mode = -1;
00243 break;
00244 default: mode = -1;
00245 }
00246 } else {
00247 SYS_MUTEX_UNLOCK( MUTEX_IO );
00248 xsb_abort("[FILE_OPEN] File opening mode must be an atom.");
00249 mode = -1;
00250 }
00251
00252 switch (mode) {
00253
00254
00255
00256
00257
00258 case OREAD: strmode = "rb"; break;
00259 case OWRITE: strmode = "wb"; break;
00260 case OAPPEND: strmode = "ab"; break;
00261 case OSTRINGR:
00262 if ((fptr = stropen(tmpstr))) {
00263 ctop_int(CTXTc 5, (Integer)fptr);
00264 } else {
00265 ctop_int(CTXTc 5, -1000);
00266 }
00267 SYS_MUTEX_UNLOCK( MUTEX_IO );
00268 return TRUE;
00269 case OSTRINGW:
00270 xsb_abort("[FILE_OPEN] Output to strings has not been implemented yet");
00271 ctop_int(CTXTc 5, -1000);
00272 SYS_MUTEX_UNLOCK( MUTEX_IO );
00273 return TRUE;
00274 default:
00275 xsb_warn("FILE_OPEN: Invalid open file mode");
00276 ctop_int(CTXTc 5, -1000);
00277 SYS_MUTEX_UNLOCK( MUTEX_IO );
00278 return TRUE;
00279 }
00280
00281
00282 addr = expand_filename(tmpstr);
00283
00284 opennew = ptoc_int(CTXTc 4);
00285 if (!xsb_intern_file("FILE_OPEN",addr, &ioport,strmode,opennew)) {
00286 open_files[ioport].stream_type = str_type;
00287 ctop_int(CTXTc 5,ioport);
00288 }
00289 else ctop_int(CTXTc 5,-1);
00290 mem_dealloc(addr,MAXPATHLEN,OTHER_SPACE);
00291
00292 SYS_MUTEX_UNLOCK( MUTEX_IO );
00293 break;
00294 }
00295
00296
00297
00298 case FILE_CLOSE:
00299 {
00300 int rtrn;
00301 io_port = ptoc_int(CTXTc 2);
00302 if (io_port < 0) {
00303 XSB_STREAM_LOCK(io_port);
00304 strclose(io_port);
00305 XSB_STREAM_UNLOCK(io_port);
00306 }
00307 else {
00308 XSB_STREAM_LOCK(io_port);
00309 SET_FILEPTR(fptr, io_port);
00310 if ((rtrn = fclose(fptr))) {
00311 if (ptoc_int(CTXTc 3) == NOFORCE_FILE_CLOSE) {
00312 XSB_STREAM_UNLOCK(io_port);
00313 xsb_permission_error(CTXTc "fclose","file",reg[2],"file_close",1);
00314 }
00315 }
00316 open_files[io_port].file_ptr = NULL;
00317 open_files[io_port].file_name = NULL;
00318 open_files[io_port].io_mode = '\0';
00319 open_files[io_port].stream_type = 0;
00320 if (pflags[CURRENT_INPUT] == (Cell) io_port)
00321 { pflags[CURRENT_INPUT] = STDIN;}
00322 if (pflags[CURRENT_OUTPUT] == (Cell) io_port)
00323 { pflags[CURRENT_OUTPUT] = STDOUT;}
00324 }
00325 XSB_STREAM_UNLOCK(io_port);
00326 break;
00327 }
00328 case FILE_GET:
00329 io_port = ptoc_int(CTXTc 2);
00330 if ((io_port < 0) && (io_port >= -MAXIOSTRS)) {
00331 XSB_STREAM_LOCK(io_port);
00332 sfptr = strfileptr(io_port);
00333 ctop_int(CTXTc 3, strgetc(sfptr));
00334 } else {
00335 SET_FILEPTR(fptr, io_port);
00336 XSB_STREAM_LOCK(io_port);
00337 ctop_int(CTXTc 3, getc(fptr));
00338 }
00339 XSB_STREAM_UNLOCK(io_port);
00340 break;
00341 case FILE_PUT:
00342 io_port = ptoc_int(CTXTc 2);
00343 XSB_STREAM_LOCK(io_port);
00344 SET_FILEPTR(fptr, io_port);
00345
00346 value = ptoc_int(CTXTc 3);
00347 putc(value, fptr);
00348 #ifdef WIN_NT
00349 if (io_port==2 && value=='\n') fflush(fptr);
00350 #endif
00351 XSB_STREAM_UNLOCK(io_port);
00352 break;
00353 case FILE_GETBUF:
00354
00355
00356
00357 size = ptoc_int(CTXTc 3);
00358 io_port = ptoc_int(CTXTc 2);
00359 XSB_STREAM_LOCK(io_port);
00360 SET_FILEPTR(fptr, io_port);
00361 XSB_StrSet(&VarBuf,"");
00362 XSB_StrEnsureSize(&VarBuf,size);
00363 value = fread(VarBuf.string, 1, size, fptr);
00364 VarBuf.length = value;
00365 XSB_StrNullTerminate(&VarBuf);
00366 XSB_STREAM_UNLOCK(io_port);
00367 ctop_string(CTXTc 4, string_find(VarBuf.string,1));
00368 ctop_int(CTXTc 5, value);
00369 break;
00370 case FILE_PUTBUF:
00371
00372
00373
00374
00375 pterm = reg_term(CTXTc 4);
00376 if (islist(pterm))
00377 addr =
00378 p_charlist_to_c_string(CTXTc pterm,&VarBuf,"FILE_WRITE_LINE","input string");
00379 else if (isstring(pterm))
00380 addr = string_val(pterm);
00381 else {
00382 xsb_abort("[FILE_PUTBUF] Output argument must be an atom or a character list");
00383 addr = NULL;
00384 }
00385 size = ptoc_int(CTXTc 3);
00386 offset = ptoc_int(CTXTc 5);
00387 length = strlen(addr);
00388 size = ( size < length - offset ? size : length - offset);
00389 io_port = ptoc_int(CTXTc 2);
00390 XSB_STREAM_LOCK(io_port);
00391 SET_FILEPTR(fptr, io_port);
00392 value = fwrite(addr+offset, 1, size, fptr);
00393 XSB_STREAM_UNLOCK(io_port);
00394 ctop_int(CTXTc 6, value);
00395 break;
00396 case FILE_READ_LINE: {
00397
00398
00399
00400
00401 char buf[MAX_IO_BUFSIZE+1];
00402 int break_loop = FALSE;
00403 int eof=FALSE;
00404
00405 io_port = ptoc_int(CTXTc 2);
00406 XSB_STREAM_LOCK(io_port);
00407 SET_FILEPTR(fptr, io_port);
00408 XSB_StrSet(&VarBuf,"");
00409
00410 do {
00411 if (fgets(buf, MAX_IO_BUFSIZE, fptr) == NULL && feof(fptr)) {
00412 eof=TRUE;
00413 break;
00414 } else {
00415 XSB_StrAppend(&VarBuf,buf);
00416 break_loop = (buf[(strlen(buf)-1)] == '\n');
00417 }
00418 } while (!break_loop);
00419
00420 ctop_string(CTXTc 3, string_find(VarBuf.string,1));
00421
00422 XSB_STREAM_UNLOCK(io_port);
00423
00424
00425 if ((VarBuf.length>0) || (!eof))
00426 return TRUE;
00427 else
00428 return FALSE;
00429 }
00430 case FILE_READ_LINE_LIST: {
00431
00432
00433
00434
00435 char *line_buff = NULL;
00436 int line_buff_len = 0;
00437 int line_buff_disp;
00438 char *atomname;
00439 int c;
00440 Cell new_list;
00441 CPtr top = NULL;
00442 int i;
00443
00444 io_port = ptoc_int(CTXTc 2);
00445 XSB_STREAM_LOCK(io_port);
00446 SET_FILEPTR(fptr, io_port);
00447
00448 line_buff_disp = 0;
00449 do {
00450 if (line_buff_disp >= line_buff_len) {
00451 int old_len = line_buff_len;
00452 line_buff_len = line_buff_disp+MAX_IO_BUFSIZE;
00453 if(!(line_buff = mem_realloc(line_buff,old_len,line_buff_len,LEAK_SPACE)))
00454 xsb_exit("No space for line buffer");
00455 }
00456 *(line_buff+line_buff_disp) = c = getc(fptr);
00457 if (c == EOF) break;
00458 line_buff_disp++;
00459 } while (c != '\n');
00460 *(line_buff+line_buff_disp) = 0;
00461
00462 check_glstack_overflow(3, pcreg, 2*sizeof(Cell)*line_buff_disp);
00463 atomname = line_buff;
00464
00465 if (line_buff_disp == 0) new_list = makenil;
00466 else {
00467 new_list = makelist(hreg);
00468 for (i = 0; i < line_buff_disp; i++) {
00469 follow(hreg++) = makeint(*(unsigned char *)atomname);
00470 atomname++;
00471 top = hreg++;
00472 follow(top) = makelist(hreg);
00473 }
00474 follow(top) = makenil;
00475 }
00476
00477 ctop_tag(CTXTc 3, new_list);
00478
00479 if (line_buff) mem_dealloc(line_buff,line_buff_len,LEAK_SPACE);
00480
00481
00482
00483
00484 XSB_STREAM_UNLOCK(io_port);
00485 if (line_buff_disp>0)
00486 return TRUE;
00487 else
00488 return FALSE;
00489 }
00490
00491
00492 case FILE_WRITE_LINE:
00493 pterm = reg_term(CTXTc 3);
00494 if (islist(pterm))
00495 addr =
00496 p_charlist_to_c_string(CTXTc pterm,&VarBuf,"FILE_WRITE_LINE","input string");
00497 else if (isstring(pterm))
00498 addr = string_val(pterm);
00499 else {
00500 xsb_abort("[FILE_WRITE_LINE] Outmput arg must be an atom or a char list");
00501 addr = NULL;
00502 }
00503 offset = ptoc_int(CTXTc 4);
00504 size = strlen(addr)-offset;
00505 io_port = ptoc_int(CTXTc 2);
00506 XSB_STREAM_LOCK(io_port);
00507 SET_FILEPTR(fptr, io_port);
00508 fwrite(addr+offset, 1, size, fptr);
00509 XSB_STREAM_UNLOCK(io_port);
00510 break;
00511
00512 case FILE_REOPEN:
00513
00514 tmpstr = ptoc_string(CTXTc 2);
00515 pterm = reg_term(CTXTc 3);
00516 if (isinteger(pterm)|isboxedinteger(pterm))
00517 mode = oint_val(pterm);
00518 else if (isstring(pterm)) {
00519 switch ((string_val(pterm))[0]) {
00520 case 'r': mode = OREAD; break;
00521 case 'w': mode = OWRITE; break;
00522 case 'a': mode = OAPPEND; break;
00523 case 's':
00524 if ((string_val(pterm))[1] == 'r')
00525
00526 mode = OSTRINGR;
00527 else if ((string_val(pterm))[1] == 'w')
00528
00529 mode = OSTRINGW;
00530 else
00531 mode = -1;
00532 break;
00533 default: mode = -1;
00534 }
00535 } else {
00536 xsb_abort("[FILE_REOPEN] Open mode must be an atom or an integer");
00537 mode = -1;
00538 }
00539
00540 switch (mode) {
00541
00542 case OREAD: strmode = "rb"; break;
00543 case OWRITE: strmode = "wb"; break;
00544 case OAPPEND: strmode = "ab"; break;
00545 case OSTRINGR:
00546 xsb_abort("[FILE_REOPEN] Reopening of strings hasn't been implemented");
00547 ctop_int(CTXTc 5, -1000);
00548 return TRUE;
00549 case OSTRINGW:
00550 xsb_abort("[FILE_REOPEN] Reopening of strings hasn't been implemented");
00551 ctop_int(CTXTc 5, -1000);
00552 return TRUE;
00553 default:
00554 xsb_warn("FILE_REOPEN: Invalid open file mode");
00555 ctop_int(CTXTc 5, -1000);
00556 return TRUE;
00557 }
00558
00559
00560 addr = expand_filename(tmpstr);
00561 io_port = ptoc_int(CTXTc 4);
00562 XSB_STREAM_LOCK(io_port);
00563 SET_FILEPTR(fptr, io_port);
00564 fflush(fptr);
00565 fptr = freopen(addr, string_val(pterm), fptr);
00566 XSB_STREAM_UNLOCK(io_port);
00567
00568 if (fptr) {
00569 struct stat stat_buff;
00570 if (!stat(addr, &stat_buff) && !S_ISDIR(stat_buff.st_mode))
00571
00572 ctop_int(CTXTc 5, 0);
00573 else {
00574 xsb_warn("FILE_REOPEN: File %s is a directory, cannot open!", addr);
00575 ctop_int(CTXTc 5, -2);
00576 }
00577 } else
00578 ctop_int(CTXTc 5, -3);
00579 mem_dealloc(addr,MAXPATHLEN,OTHER_SPACE);
00580
00581 break;
00582
00583
00584
00585
00586
00587
00588 case FILE_CLONE: {
00589
00590
00591
00592
00593 FILE *src_fptr, *dest_fptr;
00594 int src_fd, dest_fd, dest_xsb_fileno, src_xsb_fileno, errcode=0;
00595 char *mode = NULL;
00596 prolog_term dest_fptr_term;
00597
00598 src_xsb_fileno = ptoc_int(CTXTc 2);
00599 dest_fptr_term = reg_term(CTXTc 3);
00600 XSB_STREAM_LOCK(src_xsb_fileno);
00601 XSB_STREAM_LOCK(int_val(dest_fptr_term));
00602 SET_FILEPTR(src_fptr, src_xsb_fileno);
00603 fflush(src_fptr);
00604 src_fd = fileno(src_fptr);
00605
00606 if (isnonvar(dest_fptr_term)) {
00607
00608 SET_FILEPTR(dest_fptr, int_val(dest_fptr_term));
00609 dest_fd = fileno(dest_fptr);
00610 errcode = dup2(src_fd,dest_fd);
00611 } else {
00612
00613 dest_fd = dup(src_fd);
00614 if (dest_fd >= 0) {
00615 #if (defined (WIN_NT) && ! defined(CYGWIN))
00616
00617 mode = "r+";
00618 #else
00619 int fd_flags;
00620
00621 fd_flags = fcntl(dest_fd, F_GETFL) & (O_ACCMODE | O_APPEND);
00622 switch (fd_flags) {
00623 case O_RDONLY:
00624 mode = "rb";
00625 break;
00626
00627 case O_WRONLY:
00628 mode = "wb";
00629 break;
00630
00631 case O_ACCMODE:
00632
00633
00634
00635 case O_RDWR:
00636 mode = "rb+";
00637 break;
00638
00639 case O_RDONLY | O_APPEND:
00640 mode = "rb";
00641 break;
00642
00643 case O_WRONLY | O_APPEND:
00644 mode = "ab";
00645 break;
00646
00647 case O_ACCMODE | O_APPEND:
00648
00649
00650
00651 case O_RDWR | O_APPEND:
00652 mode = "ab+";
00653 break;
00654
00655 default:
00656 mode = "rb+";
00657 break;
00658 }
00659 #endif
00660 dest_fptr = fdopen(dest_fd, mode);
00661 if (dest_fptr) {
00662 dest_xsb_fileno =
00663 xsb_intern_fileptr(dest_fptr,"FILE_CLONE",
00664 open_files[src_xsb_fileno].file_name,
00665 &open_files[src_xsb_fileno].io_mode);
00666 c2p_int(CTXTc dest_xsb_fileno, dest_fptr_term);
00667 } else {
00668
00669 errcode = -1;
00670 }
00671 } else
00672
00673 errcode = -1;
00674 }
00675 ctop_int(CTXTc 4, errcode);
00676
00677 XSB_STREAM_UNLOCK(int_val(dest_fptr_term));
00678 XSB_STREAM_UNLOCK(src_xsb_fileno);
00679 break;
00680 }
00681
00682 case PIPE_OPEN: {
00683 int pipe_fd[2];
00684
00685 if (PIPE(pipe_fd) < 0) {
00686 ctop_int(CTXTc 2, PIPE_TO_PROC_FAILED);
00687 ctop_int(CTXTc 3, PIPE_FROM_PROC_FAILED);
00688 return TRUE;
00689 }
00690 ctop_int(CTXTc 2, pipe_fd[0]);
00691 ctop_int(CTXTc 3, pipe_fd[1]);
00692 break;
00693 }
00694
00695 case FD2IOPORT: {
00696
00697
00698 int pipe_fd, i;
00699 char *mode=NULL;
00700 #ifndef WIN_NT
00701 int fd_flags;
00702 #endif
00703 pipe_fd = ptoc_int(CTXTc 2);
00704 pterm = reg_term(CTXTc 4);
00705
00706 if (isstring(pterm)) {
00707 if ((string_val(pterm))[0] == 'u') {
00708
00709 #ifdef WIN_NT
00710
00711 mode = "r+";
00712 #else
00713 fd_flags = fcntl(pipe_fd, F_GETFL);
00714 if (fd_flags == O_RDONLY)
00715 mode = "rb";
00716 else if (fd_flags == O_WRONLY)
00717 mode = "wb";
00718 else {
00719
00720 mode = "r+";
00721 }
00722 #endif
00723 }
00724 else mode = string_val(pterm);
00725 }
00726 else {
00727 xsb_abort("[FD2IOPORT] Opening mode must be an atom.");
00728 mode = "x";
00729 }
00730
00731 fptr = fdopen(pipe_fd, mode);
00732
00733 SYS_MUTEX_LOCK( MUTEX_IO );
00734
00735 i = xsb_intern_fileptr(fptr, "FD2IOPORT","created from fd",mode);
00736 ctop_int(CTXTc 3, i);
00737 open_files[i].stream_type = PIPE_STREAM;
00738 SYS_MUTEX_UNLOCK( MUTEX_IO );
00739 break;
00740 }
00741
00742
00743 case FILE_CLEARERR: {
00744 io_port = ptoc_int(CTXTc 2);
00745 if ((io_port < 0) && (io_port >= -MAXIOSTRS)) {
00746 }
00747 else {
00748 XSB_STREAM_LOCK(io_port);
00749 SET_FILEPTR(fptr, io_port);
00750 clearerr(fptr);
00751 XSB_STREAM_UNLOCK(io_port);
00752 }
00753 break;
00754 }
00755
00756 case TMPFILE_OPEN: {
00757
00758
00759 SYS_MUTEX_LOCK( MUTEX_IO );
00760 if ((fptr = tmpfile()))
00761 ctop_int(CTXTc 2, xsb_intern_fileptr(fptr, "TMPFILE_OPEN",
00762 "TMPFILE","wb+"));
00763 else
00764 ctop_int(CTXTc 2, -1);
00765 SYS_MUTEX_UNLOCK( MUTEX_IO );
00766 break;
00767 }
00768
00769 case STREAM_PROPERTY: {
00770 int stream;
00771 stream = ptoc_int(CTXTc 2);
00772 XSB_STREAM_LOCK(stream);
00773 switch (ptoc_int(CTXTc 3)) {
00774
00775
00776 case STREAM_EOF_ACTION:
00777 case STREAM_REPOSITIONABLE:
00778 case STREAM_TYPE:
00779 case STREAM_CLASS:
00780 ctop_int(CTXTc 4, open_files[stream].stream_type);
00781 break;
00782
00783 case STREAM_FILE_NAME:
00784 if (open_files[stream].stream_type < 3)
00785 ctop_string(CTXTc 4, open_files[stream].file_name);
00786 break;
00787
00788 case STREAM_MODE:
00789 case STREAM_INPUT:
00790 case STREAM_OUTPUT: {
00791
00792 mode = open_files[stream].io_mode;
00793 if (mode == 'r' || mode == 's') {
00794 ctop_int(CTXTc 4,READ_MODE);
00795 } else if (mode == 'w' || mode == 'x') {
00796 ctop_int(CTXTc 4,WRITE_MODE);
00797 } else if (mode == 'a' || mode == 'b') {
00798 ctop_int(CTXTc 4,APPEND_MODE);
00799 }
00800 break;
00801 }
00802 }
00803 XSB_STREAM_UNLOCK(stream);
00804 break;
00805 }
00806
00807 case IS_VALID_STREAM: {
00808 int stream;
00809 char iomode;
00810
00811 stream = ptoc_int(CTXTc 2);
00812 if (stream >= MAX_OPEN_FILES)
00813 return FALSE;
00814 XSB_STREAM_LOCK(stream);
00815 if ((stream < 0) && (stream >= -MAXIOSTRS)) {
00816
00817 sfptr = strfileptr(stream);
00818 XSB_STREAM_UNLOCK(stream);
00819 if (sfptr == NULL) {
00820 return FALSE;
00821 }
00822 else {
00823 ctop_int(CTXTc 3,READ_MODE);
00824 return TRUE;
00825 }
00826 }
00827 if (stream < -MAXIOSTRS) {
00828 XSB_STREAM_UNLOCK(stream);
00829 return FALSE;
00830 }
00831 fptr = fileptr(stream); \
00832 if ((fptr==NULL) && (stream != 0)) {
00833 XSB_STREAM_UNLOCK(stream);
00834 return FALSE;
00835 }
00836 else {
00837 iomode = open_files[stream].io_mode;
00838 XSB_STREAM_UNLOCK(stream);
00839 if (iomode == 'r' || iomode == 's') {
00840 ctop_int(CTXTc 3,READ_MODE);
00841 } else ctop_int(CTXTc 3,WRITE_MODE);
00842 return TRUE;
00843 }
00844 }
00845
00846 case PRINT_OPENFILES: {
00847 int i;
00848 for (i= 0 ; i < MAX_OPEN_FILES ; i++) {
00849 if (open_files[i].file_name == NULL) {
00850 printf("i: %d File Ptr %p Mode %c Type %d \n",
00851 i,open_files[i].file_ptr,open_files[i].io_mode,
00852 open_files[i].stream_type);
00853 } else {
00854 printf("i; %d File Ptr %p Name %s Mode %c Type %d\n",i,
00855 open_files[i].file_ptr, open_files[i].file_name,open_files[i].io_mode,
00856 open_files[i].stream_type);
00857 }
00858 }
00859 break;
00860 }
00861
00862
00863 case FILE_END_OF_FILE: {
00864
00865 io_port = ptoc_int(CTXTc 2);
00866 XSB_STREAM_LOCK(io_port);
00867 if (io_port < 0) {
00868 sfptr = strfileptr(io_port);
00869 XSB_STREAM_UNLOCK(io_port);
00870 if (sfptr->strcnt == EOF) {
00871 XSB_STREAM_UNLOCK(io_port);
00872 return TRUE;
00873 } else {
00874 XSB_STREAM_UNLOCK(io_port);
00875 return FALSE;
00876 }
00877 }
00878 else {
00879 if (feof(open_files[ptoc_int(CTXTc 2)].file_ptr) != 0) {
00880 XSB_STREAM_UNLOCK(io_port);
00881 return TRUE;
00882 } else {
00883 XSB_STREAM_UNLOCK(io_port);
00884 return FALSE;
00885 }
00886 }
00887 }
00888
00889 case FILE_PEEK: {
00890 int bufchar;
00891
00892 io_port = ptoc_int(CTXTc 2);
00893 XSB_STREAM_LOCK(io_port);
00894 if ((io_port < 0) && (io_port >= -MAXIOSTRS)) {
00895 sfptr = strfileptr(io_port);
00896 ctop_int(CTXTc 3, strpeekc(sfptr));
00897 } else {
00898 SET_FILEPTR(fptr, io_port);
00899 bufchar = getc(fptr);
00900 ctop_int(CTXTc 3, bufchar);
00901 if (bufchar >= 0)
00902 ungetc(bufchar, fptr);
00903 }
00904 XSB_STREAM_UNLOCK(io_port);
00905 break;
00906 }
00907
00908 case XSB_STREAM_LOCK_B: {
00909 #ifdef MULTI_THREAD
00910 XSB_STREAM_LOCK(ptoc_int(CTXTc 2));
00911 #else
00912 return TRUE;
00913 #endif
00914 break;
00915 }
00916
00917 case XSB_STREAM_UNLOCK_B: {
00918 #ifdef MULTI_THREAD
00919 XSB_STREAM_UNLOCK(ptoc_int(CTXTc 2));
00920 #else
00921 return TRUE;
00922 #endif
00923 break;
00924 }
00925
00926 default:
00927 xsb_abort("[FILE_FUNCTION]: Invalid file operation, %d\n", ptoc_int(CTXTc 1));
00928 }
00929
00930 return TRUE;
00931 }
00932