wrowe 2003/03/18 18:14:36
Modified: file_io/unix filedup.c
Log:
Break the initial *new_file NULL check
apart to solve two major bugs.
1) APR attempts to defer creation of objects until the underlying atomic
call actually succeeds - in this case, dup() for the apr_file_dup()
flavor (which_dup == 1).
2) APR cannot trust the LHS point passed in via apr_file_dup(), nowhere
else do we require the user to 'NULL' out the target variable.
This patch always creates a new apr_pcalloc() for apr_file_dup()
ignoring the old value of *new_file.
Revision Changes Path
1.55 +12 -12 apr/file_io/unix/filedup.c
Index: filedup.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/filedup.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- filedup.c 19 Mar 2003 02:08:28 -0000 1.54
+++ filedup.c 19 Mar 2003 02:14:36 -0000 1.55
@@ -64,20 +64,11 @@
{
int rv;
- if ((*new_file) == NULL) {
- if (which_dup == 1) {
- (*new_file) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
- if ((*new_file) == NULL) {
- return APR_ENOMEM;
- }
- (*new_file)->pool = p;
- } else {
+ if (which_dup == 2) {
+ if ((*new_file) == NULL) {
/* We can't dup2 unless we have a valid new_file */
return APR_EINVAL;
}
- }
-
- if (which_dup == 2) {
#ifdef NETWARE
/* Apparently Netware doesn't support dup2... instead
* close() then dup()
@@ -88,12 +79,21 @@
rv = dup2(old_file->filedes, (*new_file)->filedes);
#endif
} else {
- rv = ((*new_file)->filedes = dup(old_file->filedes));
+ rv = dup(old_file->filedes);
}
if (rv == -1)
return errno;
+ if (which_dup == 1) {
+ (*new_file) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
+ if ((*new_file) == NULL) {
+ return APR_ENOMEM;
+ }
+ (*new_file)->pool = p;
+ (*new_file)->filedes = rv;
+ }
+
(*new_file)->fname = apr_pstrdup(p, old_file->fname);
(*new_file)->buffered = old_file->buffered;