~ubuntu-branches/ubuntu/feisty/apache2/feisty

0.6.1 by Andreas Barth
Import upstream version 2.2.3
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
2
 * applicable.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#include "win32/apr_arch_file_io.h"
18
#include "apr_file_io.h"
19
#include "apr_general.h"
20
#include "apr_strings.h"
21
#include <string.h>
22
#include "apr_arch_inherit.h"
23
24
APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
25
                                       apr_file_t *old_file, apr_pool_t *p)
26
{
27
#ifdef _WIN32_WCE
28
    return APR_ENOTIMPL;
29
#else
30
    HANDLE hproc = GetCurrentProcess();
31
    HANDLE newhand = NULL;
32
33
    if (!DuplicateHandle(hproc, old_file->filehand, 
34
                         hproc, &newhand, 0, FALSE, 
35
                         DUPLICATE_SAME_ACCESS)) {
36
        return apr_get_os_error();
37
    }
38
39
    (*new_file) = (apr_file_t *) apr_pcalloc(p, sizeof(apr_file_t));
40
    (*new_file)->filehand = newhand;
41
    (*new_file)->flags = old_file->flags & ~APR_INHERIT;
42
    (*new_file)->pool = p;
43
    (*new_file)->fname = apr_pstrdup(p, old_file->fname);
44
    (*new_file)->append = old_file->append;
45
    (*new_file)->buffered = FALSE;
46
    (*new_file)->ungetchar = old_file->ungetchar;
47
48
#if APR_HAS_THREADS
49
    if (old_file->mutex) {
50
        apr_thread_mutex_create(&((*new_file)->mutex),
51
                                APR_THREAD_MUTEX_DEFAULT, p);
52
    }
53
#endif
54
55
    apr_pool_cleanup_register((*new_file)->pool, (void *)(*new_file), file_cleanup,
56
                        apr_pool_cleanup_null);
57
58
    /* Create a pollset with room for one descriptor. */
59
    /* ### check return codes */
60
    (void) apr_pollset_create(&(*new_file)->pollset, 1, p, 0);
61
62
    return APR_SUCCESS;
63
#endif /* !defined(_WIN32_WCE) */
64
}
65
66
#define stdin_handle 0x01
67
#define stdout_handle 0x02
68
#define stderr_handle 0x04
69
70
APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file,
71
                                        apr_file_t *old_file, apr_pool_t *p)
72
{
73
#ifdef _WIN32_WCE
74
    return APR_ENOTIMPL;
75
#else
76
    DWORD stdhandle = 0;
77
    HANDLE hproc = GetCurrentProcess();
78
    HANDLE newhand = NULL;
79
    apr_int32_t newflags;
80
81
    /* dup2 is not supported literaly with native Windows handles.
82
     * We can, however, emulate dup2 for the standard i/o handles,
83
     * and close and replace other handles with duped handles.
84
     * The os_handle will change, however.
85
     */
86
    if (new_file->filehand == GetStdHandle(STD_ERROR_HANDLE)) {
87
        stdhandle |= stderr_handle;
88
    }
89
    if (new_file->filehand == GetStdHandle(STD_OUTPUT_HANDLE)) {
90
        stdhandle |= stdout_handle;
91
    }
92
    if (new_file->filehand == GetStdHandle(STD_INPUT_HANDLE)) {
93
        stdhandle |= stdin_handle;
94
    }
95
96
    if (stdhandle) {
97
        if (!DuplicateHandle(hproc, old_file->filehand, 
98
                             hproc, &newhand, 0,
99
                             TRUE, DUPLICATE_SAME_ACCESS)) {
100
            return apr_get_os_error();
101
        }
102
        if (((stdhandle & stderr_handle) && !SetStdHandle(STD_ERROR_HANDLE, newhand)) ||
103
            ((stdhandle & stdout_handle) && !SetStdHandle(STD_OUTPUT_HANDLE, newhand)) ||
104
            ((stdhandle & stdin_handle) && !SetStdHandle(STD_INPUT_HANDLE, newhand))) {
105
            return apr_get_os_error();
106
        }
107
        newflags = old_file->flags | APR_INHERIT;
108
    }
109
    else {
110
        if (!DuplicateHandle(hproc, old_file->filehand, 
111
                             hproc, &newhand, 0,
112
                             FALSE, DUPLICATE_SAME_ACCESS)) {
113
            return apr_get_os_error();
114
        }
115
        newflags = old_file->flags & ~APR_INHERIT;
116
    }
117
118
    if (new_file->filehand && (new_file->filehand != INVALID_HANDLE_VALUE)) {
119
        CloseHandle(new_file->filehand);
120
    }
121
122
    new_file->flags = newflags;
123
    new_file->filehand = newhand;
124
    new_file->fname = apr_pstrdup(new_file->pool, old_file->fname);
125
    new_file->append = old_file->append;
126
    new_file->buffered = FALSE;
127
    new_file->ungetchar = old_file->ungetchar;
128
129
#if APR_HAS_THREADS
130
    if (old_file->mutex) {
131
        apr_thread_mutex_create(&(new_file->mutex),
132
                                APR_THREAD_MUTEX_DEFAULT, p);
133
    }
134
#endif
135
136
    return APR_SUCCESS;
137
#endif /* !defined(_WIN32_WCE) */
138
}
139
140
APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file,
141
                                            apr_file_t *old_file,
142
                                            apr_pool_t *p)
143
{
144
    *new_file = (apr_file_t *)apr_palloc(p, sizeof(apr_file_t));
145
    memcpy(*new_file, old_file, sizeof(apr_file_t));
146
    (*new_file)->pool = p;
147
    if (old_file->buffered) {
148
        (*new_file)->buffer = apr_palloc(p, APR_FILE_BUFSIZE);
149
        if (old_file->direction == 1) {
150
            memcpy((*new_file)->buffer, old_file->buffer, old_file->bufpos);
151
        }
152
        else {
153
            memcpy((*new_file)->buffer, old_file->buffer, old_file->dataRead);
154
        }
155
    }
156
    if (old_file->mutex) {
157
        apr_thread_mutex_create(&((*new_file)->mutex),
158
                                APR_THREAD_MUTEX_DEFAULT, p);
159
        apr_thread_mutex_destroy(old_file->mutex);
160
    }
161
    if (old_file->fname) {
162
        (*new_file)->fname = apr_pstrdup(p, old_file->fname);
163
    }
164
    if (!(old_file->flags & APR_FILE_NOCLEANUP)) {
165
        apr_pool_cleanup_register(p, (void *)(*new_file), 
166
                                  file_cleanup,
167
                                  file_cleanup);
168
    }
169
170
    old_file->filehand = INVALID_HANDLE_VALUE;
171
    apr_pool_cleanup_kill(old_file->pool, (void *)old_file,
172
                          file_cleanup);
173
174
    /* Create a pollset with room for one descriptor. */
175
    /* ### check return codes */
176
    (void) apr_pollset_create(&(*new_file)->pollset, 1, p, 0);
177
178
    return APR_SUCCESS;
179
}