CVS update: php3/functions
| From: | sas | Date: | Thu, 20 May 1999 16:34:35 +0000 |
| Subject: | CVS update: php3/functions | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-5813@lists.php.net to get a copy of this message | ||
Date: Thursday May 20, 1999 @ 12:34
Author: sas
Update of /repository/php3/functions
In directory php:/tmp/cvs-serv22643/functions
Modified Files:
file.c fsock.c fsock.h
Log Message:
Rewrite of the socket buffering system. This also fixes all known issues
as documented within the code.
In this form, all updated functions work. I don't know of any problems, but
I'm eagerly awaiting Stig's "pain tests."
I've used emalloc and friends to find possible memory problems. Once we are
sure they work, they must be replaced with their respective C library calls
for persistency support.
Index: php3/functions/file.c
diff -u php3/functions/file.c:1.209 php3/functions/file.c:1.210
--- php3/functions/file.c:1.209 Sun May 16 11:14:36 1999
+++ php3/functions/file.c Thu May 20 12:34:34 1999
@@ -26,7 +26,7 @@
| Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+----------------------------------------------------------------------+
*/
-/* $Id: file.c,v 1.209 1999/05/16 15:14:36 ssb Exp $ */
+/* $Id: file.c,v 1.210 1999/05/20 16:34:34 sas Exp $ */
#ifdef THREAD_SAFE
#include "tls.h"
#endif
@@ -267,11 +267,7 @@
if (array_init(return_value)==FAILURE) {
if (issock) {
-#if WIN32|WINNT
- closesocket(socketd);
-#else
- close(socketd);
-#endif
+ SOCK_FCLOSE(socketd);
} else {
fclose(fp);
}
@@ -343,11 +339,7 @@
}
}
if (issock) {
-#if WIN32|WINNT
- closesocket(socketd);
-#else
- close(socketd);
-#endif
+ SOCK_FCLOSE(socketd);
} else {
fclose(fp);
}
@@ -412,11 +404,7 @@
}
}
if (issock) {
-#if WIN32|WINNT
- closesocket(socketd);
-#else
- close(socketd);
-#endif
+ SOCK_FCLOSE(socketd);
} else {
fclose(fp);
}
@@ -436,12 +424,8 @@
if(!_php3_is_persistent_sock(socketd)) {
#if HAVE_SHUTDOWN
shutdown(socketd, 0);
-#endif
-#if WIN32|WINNT
- closesocket(socketd);
-#else
- close(socketd);
#endif
+ SOCK_FCLOSE(socketd);
}
efree(sock);
}
@@ -656,7 +640,6 @@
int id, type;
int issock=0;
int socketd=0, *sock;
- unsigned int temp;
TLS_VARS;
if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
@@ -675,7 +658,7 @@
/* we're at the eof if the file doesn't exist */
RETURN_TRUE;
}
- if ((issock?!(recv(socketd,(char *)&temp,1,MSG_PEEK)):feof(fp))) {
+ if ((issock?SOCK_FEOF(socketd):feof(fp))) {
RETURN_TRUE;
} else {
RETURN_FALSE;
@@ -850,7 +833,7 @@
RETURN_FALSE;
}
buf = emalloc(sizeof(char) * 2);
- if (!(issock?(SOCK_FGETC(buf,socketd)):(*buf=fgetc(fp)))) {
+ if (!(issock?(*buf=SOCK_FGETC(socketd)):(*buf=fgetc(fp)))) {
efree(buf);
RETVAL_FALSE;
} else {
@@ -1210,11 +1193,7 @@
}
}
if (issock) {
-#if WIN32|WINNT
- closesocket(socketd);
-#else
- close(socketd);
-#endif
+ SOCK_FCLOSE(socketd);
} else {
fclose(fp);
}
@@ -1421,7 +1400,7 @@
return_value->value.str.len = fread(return_value->value.str.val, 1, len, fp);
return_value->value.str.val[return_value->value.str.len] = 0;
} else {
- return_value->value.str.len = _php3_sock_fread(return_value->value.str.val, len, socketd);
+ return_value->value.str.len = SOCK_FREAD(return_value->value.str.val, len, socketd);
}
if (php3_ini.magic_quotes_runtime) {
return_value->value.str.val =
_php3_addslashes(return_value->value.str.val,return_value->value.str.len,&return_value->value.str.len,1);
Index: php3/functions/fsock.c
diff -u php3/functions/fsock.c:1.94 php3/functions/fsock.c:1.95
--- php3/functions/fsock.c:1.94 Tue Apr 6 05:53:40 1999
+++ php3/functions/fsock.c Thu May 20 12:34:34 1999
@@ -27,7 +27,7 @@
| Jim Winstead (jimw@php.net) |
+----------------------------------------------------------------------+
*/
-/* $Id: fsock.c,v 1.94 1999/04/06 09:53:40 ssb Exp $ */
+/* $Id: fsock.c,v 1.95 1999/05/20 16:34:34 sas Exp $ */
#ifdef THREAD_SAFE
#include "tls.h"
#endif
@@ -88,18 +88,22 @@
struct php3i_sockbuf {
int socket;
- char *readbuf;
+ unsigned char *readbuf;
size_t readbuflen;
size_t readpos;
size_t writepos;
struct php3i_sockbuf *next;
+ char eof;
+ char persistent;
};
static struct php3i_sockbuf *phpsockbuf;
+typedef struct php3i_sockbuf php3i_sockbuf;
+
static int php3_minit_fsock(INIT_FUNC_ARGS);
-static int php3_mshutdown_fsock(void);
-static int php3_rshutdown_fsock(void);
+static int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS);
+static int php3_rshutdown_fsock(SHUTDOWN_FUNC_ARGS);
php3_module_entry fsock_module_entry = {
"Socket functions", fsock_functions, php3_minit_fsock, php3_mshutdown_fsock, NULL,
php3_rshutdown_fsock, NULL, STANDARD_MODULE_PROPERTIES
@@ -290,144 +294,156 @@
}
/* }}} */
-/* Known issues with the socket buffering code:
- * - does not work reliably with persistent sockets yet
- * (buffered data is not persistent)
- * - php3_fopen_url_wrapper() is still doing single-byte lookahead/read
- */
-/* {{{ _php3_sock_fgets() */
-int _php3_sock_fgets(char *buf, int maxlen, int socket)
+static void php_cleanup_sockbuf(int persistent)
{
- struct php3i_sockbuf *sockbuf = NULL, *tmpsockbuf;
- int bytesread, toread, len, buflen, count = 0;
- char *nl;
-
- tmpsockbuf = phpsockbuf;
- while (tmpsockbuf) {
- if (tmpsockbuf->socket == socket) {
- sockbuf = tmpsockbuf;
- break;
- }
- tmpsockbuf = tmpsockbuf->next;
- }
+ php3i_sockbuf *now, *next;
- if (sockbuf) {
- toread = sockbuf->writepos - sockbuf->readpos;
- if (toread > maxlen) {
- toread = maxlen;
- }
- if ((nl = memchr(sockbuf->readbuf + sockbuf->readpos, '\n', toread)) != NULL) {
- toread = (nl - (sockbuf->readbuf + sockbuf->readpos)) + 1;
- }
- memcpy(buf, sockbuf->readbuf + sockbuf->readpos, toread);
- sockbuf->readpos += toread;
- count += toread;
- buf += toread;
- if (sockbuf->readpos >= sockbuf->writepos) {
- sockbuf->readpos = sockbuf->writepos = 0;
+ for(now = phpsockbuf; now; now = next) {
+ next = now->next;
+ if(now->persistent == persistent) {
+ if(now->readbuf) efree(now->readbuf);
+ if(now == phpsockbuf)
+ phpsockbuf = next;
+ efree(now);
}
- if (nl != NULL) {
- /* if a newline was found, skip the recv() loop */
- goto sock_fgets_exit;
- }
}
+}
- nl = NULL;
- buflen = 0;
- while (count < maxlen && nl == NULL) {
- toread = maxlen - count;
- bytesread = recv(socket, buf, toread, 0);
- if (bytesread <= 0) {
+#define TOREAD(sock) ((sock)->writepos - (sock)->readpos)
+#define READPTR(sock) ((sock)->readbuf + (sock)->readpos)
+#define WRITEPTR(sock) ((sock)->readbuf + (sock)->writepos)
+
+static php3i_sockbuf *_php3_sock_find(int socket)
+{
+ php3i_sockbuf *buf = NULL, *tmp;
+
+ for(tmp = phpsockbuf; tmp; tmp = tmp->next)
+ if(tmp->socket == socket) {
+ buf = tmp;
break;
- }
- if ((nl = memchr(buf, '\n', bytesread)) != NULL) {
- len = (nl - buf) + 1;
- count += len;
- buf += len;
- if (len < bytesread) {
- buflen = bytesread - len;
- break;
- }
- } else {
- count += bytesread;
- buf += bytesread;
}
+
+ return buf;
+}
+
+static php3i_sockbuf *_php3_sock_create(int socket)
+{
+ php3i_sockbuf *sock;
+
+ sock = ecalloc(sizeof(*sock), 1);
+ sock->socket = socket;
+ sock->next = phpsockbuf;
+ sock->persistent = _php3_is_persistent_sock(socket);
+ phpsockbuf = sock;
+
+ return sock;
+}
+
+#define CHUNK_SIZE 2048
+
+/* this reads all available data on a socket */
+size_t _php3_sock_read(php3i_sockbuf *sock)
+{
+ char buf[CHUNK_SIZE];
+ int nr_bytes;
+ size_t nr_read = 0;
+
+ if(sock->eof) return nr_read;
+
+ while(1) {
+ nr_bytes = recv(sock->socket, buf, CHUNK_SIZE, 0);
+ if(nr_bytes > 0) {
+ sock->readbuflen += nr_bytes;
+ sock->readbuf = erealloc(sock->readbuf, sock->readbuflen);
+ memcpy(WRITEPTR(sock), buf, nr_bytes);
+ sock->writepos += nr_bytes;
+ nr_read += nr_bytes;
+ } else
+ break;
}
- if (buflen > 0) { /* there was data after the "\n" ... */
- if (sockbuf == NULL) {
- sockbuf = emalloc(sizeof(struct php3i_sockbuf));
- sockbuf->socket = socket;
- sockbuf->readbuf = emalloc(maxlen);
- sockbuf->readbuflen = maxlen;
- sockbuf->readpos = sockbuf->writepos = 0;
- sockbuf->next = phpsockbuf;
- phpsockbuf = sockbuf;
- } else {
- int needlen = sockbuf->writepos + buflen;
- if (needlen > sockbuf->readbuflen) {
- sockbuf->readbuflen += maxlen;
- sockbuf->readbuf = erealloc(sockbuf->readbuf, sockbuf->readbuflen);
- }
- }
- memcpy(sockbuf->readbuf + sockbuf->writepos, buf, buflen);
- sockbuf->writepos += buflen;
+ if(nr_bytes == 0) {
+ sock->eof = 1;
}
- sock_fgets_exit:
- *buf = '\0';
- return count;
+ return nr_read;
}
-/* }}} */
-/* {{{ _php3_sock_fread() */
+#define SOCK_FIND_AND_READ \
+ php3i_sockbuf *sock; \
+ sock = _php3_sock_find(socket); \
+ if(!sock) sock = _php3_sock_create(socket); \
+ _php3_sock_read(sock)
-int _php3_sock_fread(char *buf, int maxlen, int socket)
+int _php3_sock_fgets(char *buf, int maxlen, int socket)
{
- struct php3i_sockbuf *sockbuf = phpsockbuf;
- int bytesread, toread, count = 0;
+ char *p;
+ int ret = 0;
+ SOCK_FIND_AND_READ;
+
+ p = memchr(READPTR(sock), '\n', MIN(TOREAD(sock), maxlen - 1));
+ if(p) {
+ size_t amount = (ptrdiff_t) p - (ptrdiff_t) READPTR(sock) + 1;
+
+ memcpy(buf, READPTR(sock), amount);
+ sock->readpos += amount;
- while (sockbuf) {
- if (sockbuf->socket == socket) {
- toread = sockbuf->writepos - sockbuf->readpos;
- if (toread > maxlen) {
- toread = maxlen;
- }
- memcpy(buf, sockbuf->readbuf + sockbuf->readpos, toread);
- sockbuf->readpos += toread;
- count += toread;
- buf += toread;
- break;
- }
- sockbuf = sockbuf->next;
+ buf[amount] = '\0';
+
+ ret = amount;
}
+
+ return ret;
+}
- while (count < maxlen) {
- toread = maxlen - count;
- bytesread = recv(socket, buf, toread, 0);
- if (bytesread <= 0) {
- break;
- }
- count += bytesread;
- buf += bytesread;
+int _php3_sock_fgetc(int socket)
+{
+ int ret = EOF;
+ SOCK_FIND_AND_READ;
+
+ if(TOREAD(sock) > 0) {
+ ret = *READPTR(sock);
+ sock->readpos++;
}
- *buf = '\0';
- return count;
+ return ret;
}
-/* }}} */
+int _php3_sock_feof(int socket)
+{
+ int ret = 0;
+ SOCK_FIND_AND_READ;
+
+ if(!TOREAD(sock))
+ ret = 1;
+
+ return ret;
+}
+
+int _php3_sock_fread(char *ptr, int size, int socket)
+{
+ int ret = 0;
+ SOCK_FIND_AND_READ;
+
+ ret = MIN(TOREAD(sock), size);
+ if(ret) {
+ memcpy(ptr, READPTR(sock), ret);
+ sock->readpos += ret;
+ }
+
+ return ret;
+}
+
+
/* {{{ module start/shutdown functions */
/* {{{ _php3_sock_destroy */
-#ifndef THREAD_SAFE
static void _php3_sock_destroy(void *data)
{
int *sock = (int *) data;
close(*sock);
}
-#endif
/* }}} */
/* {{{ php3_minit_fsock */
@@ -442,28 +458,21 @@
/* }}} */
/* {{{ php3_mshutdown_fsock */
-static int php3_mshutdown_fsock(void)
+static int php3_mshutdown_fsock(SHUTDOWN_FUNC_ARGS)
{
#ifndef THREAD_SAFE
_php3_hash_destroy(&ht_socks);
_php3_hash_destroy(&ht_keys);
#endif
+ php_cleanup_sockbuf(1);
return SUCCESS;
}
/* }}} */
/* {{{ php3_rshutdown_fsock() */
-static int php3_rshutdown_fsock(void)
+static int php3_rshutdown_fsock(SHUTDOWN_FUNC_ARGS)
{
- struct php3i_sockbuf *sockbuf = phpsockbuf, *this;
-
- while (sockbuf) {
- this = sockbuf;
- sockbuf = this->next;
- efree(this->readbuf);
- efree(this);
- }
- phpsockbuf = NULL;
+ php_cleanup_sockbuf(0);
return SUCCESS;
}
Index: php3/functions/fsock.h
diff -u php3/functions/fsock.h:1.16 php3/functions/fsock.h:1.17
--- php3/functions/fsock.h:1.16 Sun Jan 24 18:53:19 1999
+++ php3/functions/fsock.h Thu May 20 12:34:35 1999
@@ -27,7 +27,7 @@
| Jim Winstead (jimw@php.net) |
+----------------------------------------------------------------------+
*/
-/* $Id: fsock.h,v 1.16 1999/01/24 23:53:19 sas Exp $ */
+/* $Id: fsock.h,v 1.17 1999/05/20 16:34:35 sas Exp $ */
#ifndef _FSOCK_H
#define _FSOCK_H
@@ -37,9 +37,11 @@
extern PHP_FUNCTION(fsockopen);
extern PHP_FUNCTION(pfsockopen);
-extern int lookup_hostname(const char *addr, struct in_addr *in);
-extern int _php3_sock_fgets(char *buf, int maxlen, int socket);
-extern int _php3_sock_fread(char *buf, int maxlen, int socket);
-extern int _php3_is_persistent_sock(int);
+int lookup_hostname(const char *addr, struct in_addr *in);
+int _php3_sock_fgets(char *buf, int maxlen, int socket);
+int _php3_sock_fread(char *buf, int maxlen, int socket);
+int _php3_sock_feof(int socket);
+int _php3_sock_fgetc(int socket);
+int _php3_is_persistent_sock(int);
#endif /* _FSOCK_H */
--
PHP Development Mailing List http://www.php.net/
To unsubscribe send an empty message to php-dev-unsubscribe@lists.php.net
For help: php-dev-help@lists.php.net