[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug] close() returns "0" when closing unopened files
From: |
Aharon Robbins |
Subject: |
Re: [bug] close() returns "0" when closing unopened files |
Date: |
Thu, 04 Dec 2008 22:42:36 +0200 |
Greetings. Re this:
> Date: Wed, 3 Dec 2008 19:03:35 +0100
> From: Seb <address@hidden>
> To: address@hidden
> Subject: [bug] close() returns "0" when closing unopened files
>
> Hello,
>
> I think this time the bug come from gawk (3.1.6). :)
>
> As a matter of fact, the standard says that close() returns 0 when it succeeds
> and another value otherwise.
>
> Theorically, this code, where getline() can't open the file so that
> close() can't close it, should not return "0":
>
> $ rm -f /tmp/none
> $ gawk 'BEGIN {f="/tmp/none"; while((getline v < f) > 0){break}; print
> close(f)}'
> 0
>
> I tested with nawk and mawk, both chose to return "-1" in this case.
>
> ++
> Seb.
You have found a bug! Thanks for the bug report. The following
patch fixes the problem and will be showing up in the gawk-stable CVS
tree shortly.
Arnold
-------------------------------------------
Thu Dec 4 22:35:05 2008 Arnold D. Robbins <address@hidden>
* io.c (redirect): Only put the new struct redirect into
the list if the file or pipe could actually be opened. Fixes
a bug with the wrong return value of close, noticed by
Seb <address@hidden>.
Index: io.c
===================================================================
RCS file: /d/mongo/cvsrep/gawk-stable/io.c,v
retrieving revision 1.15
diff -u -r1.15 io.c
--- io.c 22 Aug 2008 11:45:03 -0000 1.15
+++ io.c 4 Dec 2008 20:16:35 -0000
@@ -547,6 +547,7 @@
int fd;
const char *what = NULL;
int isdir = FALSE;
+ struct redirect redir;
switch (tree->type) {
case Node_redirect_append:
@@ -640,8 +641,7 @@
}
if (rp == NULL) {
- emalloc(rp, struct redirect *, sizeof(struct redirect),
- "redirect");
+ rp = &redir;
emalloc(str, char *, tmp->stlen+1, "redirect");
memcpy(str, tmp->stptr, tmp->stlen);
str[tmp->stlen] = '\0';
@@ -651,17 +651,11 @@
rp->iop = NULL;
rp->pid = -1;
rp->status = 0;
- /* maintain list in most-recently-used first order */
- if (red_head != NULL)
- red_head->prev = rp;
- rp->prev = NULL;
- rp->next = red_head;
- red_head = rp;
} else
str = rp->value; /* get \0 terminated string */
while (rp->fp == NULL && rp->iop == NULL) {
- if (rp->flag & RED_EOF)
+ if (rp != & redir && rp->flag & RED_EOF)
/*
* encountered EOF on file or pipe -- must be cleared
* by explicit close() before reading more
@@ -746,8 +740,9 @@
}
if (rp->fp != NULL && isatty(fd))
rp->flag |= RED_NOBUF;
+
/* Move rp to the head of the list. */
- if (red_head != rp) {
+ if (rp != & redir && red_head != rp) {
if ((rp->prev->next = rp->next) != NULL)
rp->next->prev = rp->prev;
red_head->prev = rp;
@@ -795,12 +790,30 @@
str, strerror(errno));
} else {
free_temp(tmp);
+ if (rp == & redir)
+ free(rp->value); /* don't leak
memory */
return NULL;
}
}
}
}
free_temp(tmp);
+
+ if (rp == & redir) {
+ struct redirect *rp2;
+ emalloc(rp2, struct redirect *, sizeof(struct redirect),
+ "redirect");
+ *rp2 = *rp;
+ rp = rp2;
+ /* It opened successfully, hook it into the list */
+ /* maintain list in most-recently-used first order */
+ if (red_head != NULL)
+ red_head->prev = rp;
+ rp->prev = NULL;
+ rp->next = red_head;
+ red_head = rp;
+ }
+
return rp;
}