** Return open FILE * if zFile exists, can be opened for read ** and is an ordinary file or a character stream source. ** Otherwise return 0. */
| 752 | ** Otherwise return 0. |
| 753 | */ |
| 754 | static FILE * openChrSource(const char *zFile){ |
| 755 | #ifdef _WIN32 |
| 756 | struct _stat x = {0}; |
| 757 | # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) |
| 758 | /* On Windows, open first, then check the stream nature. This order |
| 759 | ** is necessary because _stat() and sibs, when checking a named pipe, |
| 760 | ** effectively break the pipe as its supplier sees it. */ |
| 761 | FILE *rv = fopen(zFile, "rb"); |
| 762 | if( rv==0 ) return 0; |
| 763 | if( _fstat(_fileno(rv), &x) != 0 |
| 764 | || !STAT_CHR_SRC(x.st_mode)){ |
| 765 | fclose(rv); |
| 766 | rv = 0; |
| 767 | } |
| 768 | return rv; |
| 769 | #else |
| 770 | struct stat x = {0}; |
| 771 | int rc = stat(zFile, &x); |
| 772 | # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) |
| 773 | if( rc!=0 ) return 0; |
| 774 | if( STAT_CHR_SRC(x.st_mode) ){ |
| 775 | return fopen(zFile, "rb"); |
| 776 | }else{ |
| 777 | return 0; |
| 778 | } |
| 779 | #endif |
| 780 | #undef STAT_CHR_SRC |
| 781 | } |
| 782 | |
| 783 | /* |
| 784 | ** This routine reads a line of text from FILE in, stores |