summaryrefslogtreecommitdiff
path: root/Zend/zend_stream.c
blob: 1e550244e0056443f8130f934f24e9cb780a6f73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2005 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Wez Furlong <wez@thebrainroom.com>                          |
   +----------------------------------------------------------------------+
*/

/* $Id$ */


#include "zend.h"
#include "zend_compile.h"

ZEND_DLIMPORT int isatty(int fd);

static size_t zend_stream_stdio_reader(void *handle, char *buf, size_t len TSRMLS_DC)
{
	return fread(buf, 1, len, (FILE*)handle);
}

static void zend_stream_stdio_closer(void *handle TSRMLS_DC)
{
	if ((FILE*)handle != stdin)
		fclose((FILE*)handle);
}

static long zend_stream_stdio_fteller(void *handle TSRMLS_DC)
{
	return ftell((FILE*) handle);
}


ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC)
{
	if (zend_stream_open_function) {
		return zend_stream_open_function(filename, handle TSRMLS_CC);
	}
	handle->type = ZEND_HANDLE_FP;
	handle->opened_path = NULL;
	handle->handle.fp = zend_fopen(filename, &handle->opened_path);
	handle->filename = (char *)filename;
	handle->free_filename = 0;
	
	return (handle->handle.fp) ? SUCCESS : FAILURE;
}

ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC)
{
	switch (file_handle->type) {
		case ZEND_HANDLE_FILENAME:
			if (FAILURE == zend_stream_open(file_handle->filename, file_handle TSRMLS_CC)) {
				return FAILURE;
			}
			break;
			
		case ZEND_HANDLE_FD:
			file_handle->handle.fp = fdopen(file_handle->handle.fd, "rb");
			file_handle->type = ZEND_HANDLE_FP;
			break;
			
		case ZEND_HANDLE_FP:
			file_handle->handle.fp = file_handle->handle.fp;
			break;
			
		case ZEND_HANDLE_STREAM:
			/* nothing to do */
			return SUCCESS;
			
		default:
			return FAILURE;
	}
	if (file_handle->type == ZEND_HANDLE_FP) {
		if (!file_handle->handle.fp) {
			return FAILURE;
		}

		/* make compatible with stream */
		file_handle->handle.stream.handle = file_handle->handle.fp;
		file_handle->handle.stream.reader = zend_stream_stdio_reader;
		file_handle->handle.stream.closer = zend_stream_stdio_closer;
		file_handle->handle.stream.fteller = zend_stream_stdio_fteller;

		file_handle->handle.stream.interactive = isatty(fileno((FILE *)file_handle->handle.stream.handle));
	}
	return SUCCESS;
}

ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC)
{
	if (file_handle->handle.stream.interactive) {
		int c = '*';
		size_t n; 

#ifdef NETWARE
		/*
			c != 4 check is there as fread of a character in NetWare LibC gives 4 upon ^D character.
			Ascii value 4 is actually EOT character which is not defined anywhere in the LibC
			or else we can use instead of hardcoded 4.
		*/
                for ( n = 0; n < len && (c = zend_stream_getc( file_handle TSRMLS_CC)) != EOF && c != 4 && c != '\n'; ++n )
#else
		for ( n = 0; n < len && (c = zend_stream_getc( file_handle TSRMLS_CC)) != EOF && c != '\n'; ++n ) 
#endif
			buf[n] = (char) c; 
		if ( c == '\n' )
			buf[n++] = (char) c; 

		return n;
	}
	return file_handle->handle.stream.reader(file_handle->handle.stream.handle, buf, len TSRMLS_CC);
}

ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC)
{
	char buf;

	if (file_handle->handle.stream.reader(file_handle->handle.stream.handle, &buf, sizeof(buf) TSRMLS_CC)) {
		return (int)buf;
	}
	return EOF;
}

ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC)
{
	return 0;
}

ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC)
{
	return file_handle->handle.stream.fteller(file_handle->handle.stream.handle TSRMLS_CC);
}