]> granicus.if.org Git - php/commitdiff
Avoid leaking fd's in case of failures
authorZeev Suraski <zeev@php.net>
Sat, 22 May 1999 02:13:01 +0000 (02:13 +0000)
committerZeev Suraski <zeev@php.net>
Sat, 22 May 1999 02:13:01 +0000 (02:13 +0000)
Zend/zend-scanner.l
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_globals.h
Zend/zend_llist.c
Zend/zend_llist.h

index 36f06250120f703fa968ef75b3d60a10da968e4a..2e3006574c8beadc6516106aa721a27a06f168cb 100644 (file)
@@ -162,29 +162,28 @@ inline void restore_lexical_state(zend_lex_state *lex_state CLS_DC)
 
 
 BEGIN_EXTERN_C()
-ZEND_API void zend_close_file_handle(zend_file_handle *file_handle)
+
+
+ZEND_API void zend_open_file_dtor(void *f)
 {
-       switch (file_handle->type) {
-               case ZEND_HANDLE_FILENAME:
-                       break;
-               case ZEND_HANDLE_FD:
-                       close(file_handle->handle.fd);
-                       break;
-               case ZEND_HANDLE_FP:
-                       if (file_handle->handle.fp != stdin) {
-                               fclose(file_handle->handle.fp);
-                       }
-                       break;
 #ifdef ZTS
-               case ZEND_HANDLE_ISTREAM:
-                       if (file_handle->handle.is != &cin) {
-                               delete file_handle->handle.is;
-                       }
-                       break;
+       delete *((ifstream **) f);
+#else
+       fclose(*((FILE **) f));
 #endif
-       }
 }
 
+
+ZEND_API void zend_close_file_handle(zend_file_handle *file_handle CLS_DC)
+{
+#ifdef ZTS
+       zend_llist_del_element(&CG(open_files), &file_handle->handle.is);
+#else
+       zend_llist_del_element(&CG(open_files), &file_handle->handle.fp);
+#endif
+}
+
+
 ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
 {
 #ifndef ZTS
@@ -202,8 +201,10 @@ ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
        if (!file_handle->handle.fp) {
                return FAILURE;
        }
-       file_handle->type = ZEND_HANDLE_FP;
-       
+       if (file_handle->handle.fp != stdin) {
+               zend_llist_add_element(&CG(open_files), &file_handle->handle.fp);
+       }
+       file_handle->type = ZEND_HANDLE_FP;     
        /* Reset the scanner for scanning the new file */
        yyin = file_handle->handle.fp;
        yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
@@ -229,6 +230,9 @@ ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
                delete file_handle->handle.is;
                return FAILURE;
        }
+       if (file_handle->handle.is != &cin) {
+               zend_llist_add_element(&CG(open_files), &file_handle->handle.is);
+       }
        file_handle->type = ZEND_HANDLE_ISTREAM;
 
        CG(ZFL) = new ZendFlexLexer;
@@ -282,7 +286,7 @@ ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count,
                } else {
                        CG(active_op_array) = op_array;
                        compiler_result = zendparse(CLS_C);
-                       zend_close_file_handle(file_handle);
+                       zend_close_file_handle(file_handle CLS_CC);
                        restore_lexical_state(&original_lex_state CLS_CC);
                        CG(active_op_array) = original_active_op_array;
                        if (compiler_result==1) { /* parser error */
@@ -421,7 +425,7 @@ int require_file(zend_file_handle *file_handle CLS_DC)
                return FAILURE;
        }
        compiler_result = zendparse(CLS_C);
-       zend_close_file_handle(file_handle);
+       zend_close_file_handle(file_handle CLS_CC);
        restore_lexical_state(&original_lex_state CLS_CC);
        if (compiler_result==1) {
                zend_bailout();
@@ -444,7 +448,7 @@ int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlight
                return FAILURE;
        }
        zend_highlight(syntax_highlighter_ini);
-       zend_close_file_handle(&file_handle);
+       zend_close_file_handle(&file_handle CLS_CC);
        restore_lexical_state(&original_lex_state CLS_CC);
        return SUCCESS;
 }
index 99389d65ccf4dd7bf493e59e27b5d764a5dd6676..f13d3b07d1be7fb58bac4095d8871432c84df559 100644 (file)
@@ -67,6 +67,7 @@ void init_compiler(CLS_D ELS_DC)
        zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_request_startup);
        init_resource_list(ELS_C);
        CG(unclean_shutdown) = 0;
+       zend_llist_init(&CG(open_files), sizeof(void *), zend_open_file_dtor, 0);
 }
 
 
@@ -80,6 +81,7 @@ void shutdown_compiler(CLS_D)
        zend_hash_apply(CG(function_table), (int (*)(void *)) is_not_internal_function);
        zend_hash_apply(CG(class_table), (int (*)(void *)) is_not_internal_class);
        zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_cleanup);
+       zend_llist_destroy(&CG(open_files));
 }
 
 
index fde66463fcf1aee8e7f882789b47cc227dc7426f..f2ea910f0796ea1a75c42d5fadfe34ca45d65a67 100644 (file)
@@ -342,7 +342,8 @@ ZEND_API zend_op_array *compile_filename(zval *filename CLS_DC);
 ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC);
 ZEND_API void init_op_array(zend_op_array *op_array, int initial_ops_size);
 ZEND_API void destroy_op_array(zend_op_array *op_array);
-ZEND_API void zend_close_file_handle(zend_file_handle *file_handle);
+ZEND_API void zend_close_file_handle(zend_file_handle *file_handle CLS_DC);
+ZEND_API void zend_open_file_dtor(void *f);
 END_EXTERN_C()
 
 ZEND_API void destroy_zend_function(zend_function *function);
index a2036ac5435894a0c7021b9a09a73e5bf0524a24..b9d4b615908b40b64fde7005955d9719be621952 100644 (file)
@@ -147,6 +147,8 @@ struct _zend_compiler_globals {
        unsigned char handle_op_arrays; /* run op_arrays through op_array handlers */
 
        unsigned char unclean_shutdown;
+
+       zend_llist open_files;
 #ifdef ZTS
 #ifdef __cplusplus
        ZendFlexLexer *ZFL;
index 2f5a011d4d6dc4283b27fc475f19ab2d452f0168..232612be4e0fbac48d121780eb7e3ea086f225c8 100644 (file)
@@ -64,7 +64,7 @@ ZEND_API void zend_llist_del_element(zend_llist *l, void *element)
        zend_llist_element *current=l->head;
 
        while (current) {
-               if (current->data == element) {
+               if (!memcmp(current->data, element, l->size)) {
                        if (current->prev) {
                                current->prev->next = current->next;
                        } else {
index 6d2e3e83ba4a5b764f5163df3c2d82524f880e2d..dd5bedb6bf07af2c38e38f930908157bbd5c911a 100644 (file)
@@ -34,6 +34,7 @@ typedef struct {
        zend_llist_element *traverse_ptr;
 } zend_llist;
 
+BEGIN_EXTERN_C()
 ZEND_API void zend_llist_init(zend_llist *l, size_t size, void (*dtor)(void *data), unsigned char persistent);
 ZEND_API void zend_llist_add_element(zend_llist *l, void *element);
 ZEND_API void zend_llist_prepend_element(zend_llist *l, void *element);
@@ -51,5 +52,6 @@ ZEND_API void *zend_llist_get_first(zend_llist *l);
 ZEND_API void *zend_llist_get_last(zend_llist *l);
 ZEND_API void *zend_llist_get_next(zend_llist *l);
 ZEND_API void *zend_llist_get_prev(zend_llist *l);
+END_EXTERN_C()
 
 #endif /* _ZEND_LLIST_H */