]> granicus.if.org Git - php/commitdiff
fixed readfile() fd-leak.
authorThies C. Arntzen <thies@php.net>
Sun, 14 Jan 2001 14:11:38 +0000 (14:11 +0000)
committerThies C. Arntzen <thies@php.net>
Sun, 14 Jan 2001 14:11:38 +0000 (14:11 +0000)
guys, always remember that every function that *generates output* could cause a
bailout if ignore_user_abort is set to false (and the user _aborts_ the
connection). in this case a longjump will be performed and our function (in
this case readfile) will have no chance to clean-up. having said that it's a
good idea to register all opened files using REGISTER_RESOURCE - that way the
engine will make sure they get closed on request end.

ext/standard/file.c

index c8d605b41e8f5b18a0281bbb6ad36c07c17df64b..284f1384f1098a339c943b13fae1dd7e934eb20c 100644 (file)
@@ -1395,6 +1395,7 @@ PHP_FUNCTION(readfile)
        int size=0;
        int use_include_path=0;
        int issock=0, socketd=0;
+       int rsrc_id;
        
        /* check args */
        switch (ARG_COUNT(ht)) {
@@ -1429,14 +1430,21 @@ PHP_FUNCTION(readfile)
                }
                RETURN_FALSE;
        }
-       if (php_header()) {
-               size = php_passthru_fd(socketd, fp, issock);
-       }
+
        if (issock) {
-               SOCK_FCLOSE(socketd);
+               int *sock=emalloc(sizeof(int));
+               *sock = socketd;
+               rsrc_id = ZEND_REGISTER_RESOURCE(NULL,sock,php_file_le_socket());
        } else {
-               fclose(fp);
+               rsrc_id = ZEND_REGISTER_RESOURCE(NULL,fp,php_file_le_fopen());
        }
+
+       if (php_header()) {
+               size = php_passthru_fd(socketd, fp, issock);
+       }
+
+       zend_list_delete(rsrc_id);
+
        RETURN_LONG(size);
 }