bug-gnu-utils
[Top][All Lists]
Advanced

[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;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]