* Mangement of fdtable[] @ 2015-10-16 0:22 Bart Schaefer 2015-10-16 9:56 ` Chi Hsuan Yen ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Bart Schaefer @ 2015-10-16 0:22 UTC (permalink / raw) To: zsh-workers I was puzzling over Yen Chi Hsuan's bug report in 36866 so was looking through tcp.c and noticed that it opens file descriptors with socket() without marking them used in fdtable[]. The only time they're handled "properly" is with "ztcp -l" which makes a movefd() call. I think this means some fds may be closed in some cases they shouldn't, or conversely left open in cases they shouldn't. This may apply to fds in other modules, e.g., the descriptor from gdbm_open() in db_gdbm.c. This further led me to notice that when descriptors are manipulated in utils.c, it carefully calls the static check_fd_table() function every time to be sure the descriptor has a slot in the table before an FDT_* value is poked for it. Other parts of the code (mostly exec.c) simply reference fdtable[N] without error checking. I guess this is OK because fdtable[] is allocated zopenmax() slots in zsh_main(), but it seems inconsistent if not actually wrong. Comments? -- Barton E. Schaefer ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-16 0:22 Mangement of fdtable[] Bart Schaefer @ 2015-10-16 9:56 ` Chi Hsuan Yen 2015-10-16 19:44 ` Peter Stephenson 2015-10-24 18:16 ` Peter Stephenson 2 siblings, 0 replies; 11+ messages in thread From: Chi Hsuan Yen @ 2015-10-16 9:56 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-workers [-- Attachment #1: Type: text/plain, Size: 1447 bytes --] Dear Bart, Thanks for digging my problem. In fact my codes uses zsocket. I think they're similar and they actually cause the same bug. I give a TCP example because I think it's easier to reproduce on different platforms. In Src/Modules/socket.c, fdtable is checked but not updated. Maybe it sould be fixed, too? Best Regards, Yen Chi Hsuan On 16 October 2015 at 08:22, Bart Schaefer <schaefer@brasslantern.com> wrote: > I was puzzling over Yen Chi Hsuan's bug report in 36866 so was looking > through tcp.c and noticed that it opens file descriptors with socket() > without marking them used in fdtable[]. The only time they're handled > "properly" is with "ztcp -l" which makes a movefd() call. > > I think this means some fds may be closed in some cases they shouldn't, > or conversely left open in cases they shouldn't. This may apply to fds > in other modules, e.g., the descriptor from gdbm_open() in db_gdbm.c. > > This further led me to notice that when descriptors are manipulated in > utils.c, it carefully calls the static check_fd_table() function every > time to be sure the descriptor has a slot in the table before an FDT_* > value is poked for it. Other parts of the code (mostly exec.c) simply > reference fdtable[N] without error checking. > > I guess this is OK because fdtable[] is allocated zopenmax() slots in > zsh_main(), but it seems inconsistent if not actually wrong. > > Comments? > > -- > Barton E. Schaefer > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-16 0:22 Mangement of fdtable[] Bart Schaefer 2015-10-16 9:56 ` Chi Hsuan Yen @ 2015-10-16 19:44 ` Peter Stephenson 2015-10-24 18:16 ` Peter Stephenson 2 siblings, 0 replies; 11+ messages in thread From: Peter Stephenson @ 2015-10-16 19:44 UTC (permalink / raw) To: zsh-workers On Thu, 15 Oct 2015 17:22:52 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > I was puzzling over Yen Chi Hsuan's bug report in 36866 so was looking > through tcp.c and noticed that it opens file descriptors with socket() > without marking them used in fdtable[]. The only time they're handled > "properly" is with "ztcp -l" which makes a movefd() call. > > I think this means some fds may be closed in some cases they shouldn't, > or conversely left open in cases they shouldn't. This may apply to fds > in other modules, e.g., the descriptor from gdbm_open() in db_gdbm.c. Highly likely; this is probably just wrong. > This further led me to notice that when descriptors are manipulated in > utils.c, it carefully calls the static check_fd_table() function every > time to be sure the descriptor has a slot in the table before an FDT_* > value is poked for it. Other parts of the code (mostly exec.c) simply > reference fdtable[N] without error checking. > > I guess this is OK because fdtable[] is allocated zopenmax() slots in > zsh_main(), but it seems inconsistent if not actually wrong. A lot of the fd code in exec.c is actually involved with opening the fd as a redirection in the first place, so it might actually be correct. pws ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-16 0:22 Mangement of fdtable[] Bart Schaefer 2015-10-16 9:56 ` Chi Hsuan Yen 2015-10-16 19:44 ` Peter Stephenson @ 2015-10-24 18:16 ` Peter Stephenson 2015-10-24 18:43 ` Bart Schaefer 2 siblings, 1 reply; 11+ messages in thread From: Peter Stephenson @ 2015-10-24 18:16 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-workers On Thu, 15 Oct 2015 17:22:52 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > I was puzzling over Yen Chi Hsuan's bug report in 36866 so was looking > through tcp.c and noticed that it opens file descriptors with socket() > without marking them used in fdtable[]. The only time they're handled > "properly" is with "ztcp -l" which makes a movefd() call. Is this the fix for tcp.c (not socket.c)? I couldn't see any obvious missing places since there appears to be strictly one fd per session so there is only a single case for closing, and the only non-standard point at which an fd is created is with listen(), giving two cases for opening. I added a different fd type because although the sockets can be used directly by users (as with FDT_EXTERNAL), they shouldn't be closed by the normal explicit shell syntax because that leaves other stuff dangling. I didn't think FDT_INTERNAL was the right thing, on balance, as they're too public for the shell taking over management to be the right thing to do. For simiilar reasons, I don't think CLOEXEC behaviour is wanted --- the user gets to decide when and where the fd is usable. pws diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c index bc1765d..8e8ed92 100644 --- a/Src/Modules/tcp.c +++ b/Src/Modules/tcp.c @@ -236,6 +236,8 @@ tcp_socket(int domain, int type, int protocol, int ztflags) if (!sess) return NULL; sess->fd = socket(domain, type, protocol); + /* We'll check failure and tidy up in caller */ + addmodulefd(sess->fd); return sess; } @@ -298,7 +300,7 @@ tcp_close(Tcp_session sess) { if (sess->fd != -1) { - err = close(sess->fd); + err = zclose(sess->fd); if (err) zwarn("connection close failed: %e", errno); } @@ -546,6 +548,9 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } + /* redup expects fd is already registered */ + addmodulefd(rfd); + if (targetfd) { sess->fd = redup(rfd, targetfd); if (sess->fd < 0) { diff --git a/Src/utils.c b/Src/utils.c index 61cbe84..b4de6c1 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1892,6 +1892,25 @@ redup(int x, int y) } /* + * Add an fd opened by external means within a module. + * Although the fd can be used within the shell for normal I/O, it can + * only be closed by the module (which should included zclose() as part + * of the sequence). + * Safe if fd is -1 to indicate failure. + */ +/**/ +mod_export void +addmodulefd(int fd) +{ + if (fd >= 0) { + check_fd_table(fd); + fdtable[fd] = FDT_MODULE; + } +} + +/**/ + +/* * Indicate that an fd has a file lock; if cloexec is 1 it will be closed * on exec. * The fd should already be known to fdtable (e.g. by movefd). diff --git a/Src/zsh.h b/Src/zsh.h index 15fa5e4..f819249 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -406,25 +406,32 @@ enum { */ #define FDT_EXTERNAL 2 /* + * Entry visible to other processes but controlled by a module. + * The difference from FDT_EXTERNAL is that closing this using + * standard fd syntax will fail as there is some tidying up that + * needs to be done by the module's own mechanism. + */ +#define FDT_MODULE 3 +/* * Entry used by output from the XTRACE option. */ -#define FDT_XTRACE 3 +#define FDT_XTRACE 4 /* * Entry used for file locking. */ -#define FDT_FLOCK 4 +#define FDT_FLOCK 5 /* * As above, but the fd is not marked for closing on exec, * so the shell can still exec the last process. */ -#define FDT_FLOCK_EXEC 5 +#define FDT_FLOCK_EXEC 6 #ifdef PATH_DEV_FD /* * Entry used by a process substition. * This marker is not tested internally as we associated the file * descriptor with a job for closing. */ -#define FDT_PROC_SUBST 6 +#define FDT_PROC_SUBST 7 #endif /* Flags for input stack */ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-24 18:16 ` Peter Stephenson @ 2015-10-24 18:43 ` Bart Schaefer 2015-10-24 19:14 ` Peter Stephenson 0 siblings, 1 reply; 11+ messages in thread From: Bart Schaefer @ 2015-10-24 18:43 UTC (permalink / raw) To: zsh-workers On Oct 24, 7:16pm, Peter Stephenson wrote: } Subject: Re: Mangement of fdtable[] } } Is this the fix for tcp.c (not socket.c)? This looks very similar to what I was contemplating, except that I had not yet thought as far as adding another FDT_* flag. The only other thing I was wondering about is allowing the module to control whether the FD is closed when entering a subshell [i.e., when exec.c calls closem(FDT_INTERNAL)], because there is not always an execv() in that case so simply setting CLOEXEC in the module is not enough. } I didn't think FDT_INTERNAL was the right thing, on balance, } as they're too public for the shell taking over management That's true for tcp.c, but perhaps not so for e.g. db_gdbm.c. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-24 18:43 ` Bart Schaefer @ 2015-10-24 19:14 ` Peter Stephenson 2015-10-24 19:37 ` Bart Schaefer 2015-10-24 19:43 ` Peter Stephenson 0 siblings, 2 replies; 11+ messages in thread From: Peter Stephenson @ 2015-10-24 19:14 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-workers On Sat, 24 Oct 2015 11:43:52 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > On Oct 24, 7:16pm, Peter Stephenson wrote: > } Subject: Re: Mangement of fdtable[] > } > } Is this the fix for tcp.c (not socket.c)? > > This looks very similar to what I was contemplating, except that I had > not yet thought as far as adding another FDT_* flag. The only other > thing I was wondering about is allowing the module to control whether > the FD is closed when entering a subshell [i.e., when exec.c calls > closem(FDT_INTERNAL)], because there is not always an execv() in that > case so simply setting CLOEXEC in the module is not enough. > > } I didn't think FDT_INTERNAL was the right thing, on balance, > } as they're too public for the shell taking over management > > That's true for tcp.c, but perhaps not so for e.g. db_gdbm.c. So that means addmodulefd() should have an additional argument saying if the fd is to be treated as internal. I don't want to add a different category saying it can be closed on exec but not by standard shell syntax since I'll get that wrong. diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c index bc1765d..274f01f 100644 --- a/Src/Modules/tcp.c +++ b/Src/Modules/tcp.c @@ -236,6 +236,8 @@ tcp_socket(int domain, int type, int protocol, int ztflags) if (!sess) return NULL; sess->fd = socket(domain, type, protocol); + /* We'll check failure and tidy up in caller */ + addmodulefd(sess->fd, FALSE); return sess; } @@ -298,7 +300,7 @@ tcp_close(Tcp_session sess) { if (sess->fd != -1) { - err = close(sess->fd); + err = zclose(sess->fd); if (err) zwarn("connection close failed: %e", errno); } @@ -546,6 +548,9 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } + /* redup expects fd is already registered */ + addmodulefd(rfd, FALSE); + if (targetfd) { sess->fd = redup(rfd, targetfd); if (sess->fd < 0) { diff --git a/Src/utils.c b/Src/utils.c index 61cbe84..4c69d75 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1892,6 +1892,32 @@ redup(int x, int y) } /* + * Add an fd opened ithin a module. + * + * If is_internal is FALSE, the fd can be used within the shell for + * normal I/O but it will not be closed automatically or by normal shell + * syntax; it can only be closed by the module (which should included + * zclose() as part of the sequence). + * + * If is_internal is TRUE the fd is treated like others created by the + * shell for internall use; it can be closed and will be closed by the + * shell if it exec's or performs an exec with a fork optimised out. + *. + * Safe if fd is -1 to indicate failure. + */ +/**/ +mod_export void +addmodulefd(int fd, bool is_internal) +{ + if (fd >= 0) { + check_fd_table(fd); + fdtable[fd] = is_internal ? FDT_INTERNAL : FDT_MODULE; + } +} + +/**/ + +/* * Indicate that an fd has a file lock; if cloexec is 1 it will be closed * on exec. * The fd should already be known to fdtable (e.g. by movefd). diff --git a/Src/zsh.h b/Src/zsh.h index 15fa5e4..f819249 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -406,25 +406,32 @@ enum { */ #define FDT_EXTERNAL 2 /* + * Entry visible to other processes but controlled by a module. + * The difference from FDT_EXTERNAL is that closing this using + * standard fd syntax will fail as there is some tidying up that + * needs to be done by the module's own mechanism. + */ +#define FDT_MODULE 3 +/* * Entry used by output from the XTRACE option. */ -#define FDT_XTRACE 3 +#define FDT_XTRACE 4 /* * Entry used for file locking. */ -#define FDT_FLOCK 4 +#define FDT_FLOCK 5 /* * As above, but the fd is not marked for closing on exec, * so the shell can still exec the last process. */ -#define FDT_FLOCK_EXEC 5 +#define FDT_FLOCK_EXEC 6 #ifdef PATH_DEV_FD /* * Entry used by a process substition. * This marker is not tested internally as we associated the file * descriptor with a job for closing. */ -#define FDT_PROC_SUBST 6 +#define FDT_PROC_SUBST 7 #endif /* Flags for input stack */ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-24 19:14 ` Peter Stephenson @ 2015-10-24 19:37 ` Bart Schaefer 2015-10-24 19:43 ` Peter Stephenson 1 sibling, 0 replies; 11+ messages in thread From: Bart Schaefer @ 2015-10-24 19:37 UTC (permalink / raw) To: zsh-workers On Oct 24, 8:14pm, Peter Stephenson wrote: } Subject: Re: Mangement of fdtable[] } } +mod_export void } +addmodulefd(int fd, bool is_internal) My compiler chokes on "bool". ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-24 19:14 ` Peter Stephenson 2015-10-24 19:37 ` Bart Schaefer @ 2015-10-24 19:43 ` Peter Stephenson 2015-10-24 21:05 ` Bart Schaefer 1 sibling, 1 reply; 11+ messages in thread From: Peter Stephenson @ 2015-10-24 19:43 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-workers On Sat, 24 Oct 2015 20:14:39 +0100 Peter Stephenson <p.w.stephenson@ntlworld.com> wrote: > So that means addmodulefd() should have an additional argument saying if > the fd is to be treated as internal. That's not good enough. For zsocket, it needs to be an FDT_EXTERNAL because we want the user to determine whne it gets closed just the same as with ztcp, but in this case it can only be closed with standard shell syntax --- I've clarified this. pws diff --git a/Doc/Zsh/mod_socket.yo b/Doc/Zsh/mod_socket.yo index 332c551..867f608 100644 --- a/Doc/Zsh/mod_socket.yo +++ b/Doc/Zsh/mod_socket.yo @@ -28,6 +28,11 @@ will be taken as the target file descriptor for the connection. In order to elicit more verbose output, use tt(-v). + +File descriptors can be closed with normal shell syntax when no longer +needed, for example: + +example(exec {REPLY}>&-) ) enditem() diff --git a/Src/Modules/socket.c b/Src/Modules/socket.c index 65b87d7..f683496 100644 --- a/Src/Modules/socket.c +++ b/Src/Modules/socket.c @@ -115,6 +115,8 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } + addmodulefd(sfd, FDT_EXTERNAL); + if (targetfd) { sfd = redup(sfd, targetfd); } @@ -127,6 +129,9 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } + /* allow to be closed explicitly */ + fdtable[sfd] = FDT_EXTERNAL; + setiparam("REPLY", sfd); if (verbose) @@ -200,12 +205,16 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } + addmodulefd(rfd, FDT_EXTERNAL); + if (targetfd) { sfd = redup(rfd, targetfd); if (sfd < 0) { zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno); + zclose(rfd); return 1; } + fdtable[sfd] = FDT_EXTERNAL; } else { sfd = rfd; @@ -240,12 +249,16 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func)) } else { + addmodulefd(sfd, FDT_EXTERNAL); + if (targetfd) { - sfd = redup(sfd, targetfd); - if (sfd < 0) { + if (redup(sfd, targetfd) < 0) { zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno); + zclose(sfd); return 1; } + sfd = targetfd; + fdtable[sfd] = FDT_EXTERNAL; } setiparam("REPLY", sfd); diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c index 274f01f..7b0dcc7 100644 --- a/Src/Modules/tcp.c +++ b/Src/Modules/tcp.c @@ -237,7 +237,7 @@ tcp_socket(int domain, int type, int protocol, int ztflags) sess->fd = socket(domain, type, protocol); /* We'll check failure and tidy up in caller */ - addmodulefd(sess->fd, FALSE); + addmodulefd(sess->fd, FDT_MODULE); return sess; } @@ -549,7 +549,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) } /* redup expects fd is already registered */ - addmodulefd(rfd, FALSE); + addmodulefd(rfd, FDT_MODULE); if (targetfd) { sess->fd = redup(rfd, targetfd); diff --git a/Src/utils.c b/Src/utils.c index 4c69d75..37a02c5 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1894,24 +1894,29 @@ redup(int x, int y) /* * Add an fd opened ithin a module. * - * If is_internal is FALSE, the fd can be used within the shell for - * normal I/O but it will not be closed automatically or by normal shell - * syntax; it can only be closed by the module (which should included - * zclose() as part of the sequence). + * fdt is the type of the fd; see the FDT_ definitions in zsh.h. + * The most likely falures are: + * + * FDT_EXTERNAL: the fd can be used within the shell for normal I/O but + * it will not be closed automatically or by normal shell syntax. + * + * FDT_MODULE: as FDT_EXTERNAL, but it can only be closed by the module + * (which should included zclose() as part of the sequence, not by + * the standard shell syntax for closing file descriptors. + * + * FDT_INTERNAL: fd is treated like others created by the shell for + * internall use; it can be closed and will be closed by the shell if it + * exec's or performs an exec with a fork optimised out. * - * If is_internal is TRUE the fd is treated like others created by the - * shell for internall use; it can be closed and will be closed by the - * shell if it exec's or performs an exec with a fork optimised out. - *. * Safe if fd is -1 to indicate failure. */ /**/ mod_export void -addmodulefd(int fd, bool is_internal) +addmodulefd(int fd, int fdt) { if (fd >= 0) { check_fd_table(fd); - fdtable[fd] = is_internal ? FDT_INTERNAL : FDT_MODULE; + fdtable[fd] = fdt; } } ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-24 19:43 ` Peter Stephenson @ 2015-10-24 21:05 ` Bart Schaefer 2015-10-25 18:44 ` Peter Stephenson 0 siblings, 1 reply; 11+ messages in thread From: Bart Schaefer @ 2015-10-24 21:05 UTC (permalink / raw) To: zsh-workers On Oct 24, 8:43pm, Peter Stephenson wrote: } Subject: Re: Mangement of fdtable[] } } That's not good enough. For zsocket, it needs to be an FDT_EXTERNAL } because we want the user to determine whne it gets closed just the same } as with ztcp, but in this case it can only be closed with standard shell } syntax --- I've clarified this. OK, so the next question is, if the descriptor is going to be closed by some external library (again I refer to db_gdbm.c), how should the module mark it as no longer used in fdtable? Poke FDT_UNUSED directly? ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-24 21:05 ` Bart Schaefer @ 2015-10-25 18:44 ` Peter Stephenson 2015-10-26 1:15 ` Bart Schaefer 0 siblings, 1 reply; 11+ messages in thread From: Peter Stephenson @ 2015-10-25 18:44 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-workers On Sat, 24 Oct 2015 14:05:39 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > On Oct 24, 8:43pm, Peter Stephenson wrote: > } Subject: Re: Mangement of fdtable[] > } > } That's not good enough. For zsocket, it needs to be an FDT_EXTERNAL > } because we want the user to determine whne it gets closed just the same > } as with ztcp, but in this case it can only be closed with standard shell > } syntax --- I've clarified this. > > OK, so the next question is, if the descriptor is going to be closed by > some external library (again I refer to db_gdbm.c), how should the > module mark it as no longer used in fdtable? Poke FDT_UNUSED directly? I guess so, it's just the rest of zclose() apart from the close itself. I'm wondering if really we should be using bit fields rather than categories --- so there's a bit for close when we call closem(), a bit for this is managed by a module, a bit for external, etc. That probably scales a lot better than what we've currently got. pws ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Mangement of fdtable[] 2015-10-25 18:44 ` Peter Stephenson @ 2015-10-26 1:15 ` Bart Schaefer 0 siblings, 0 replies; 11+ messages in thread From: Bart Schaefer @ 2015-10-26 1:15 UTC (permalink / raw) To: zsh-workers On Oct 25, 6:44pm, Peter Stephenson wrote: } Subject: Re: Mangement of fdtable[] } } On Sat, 24 Oct 2015 14:05:39 -0700 } Bart Schaefer <schaefer@brasslantern.com> wrote: } > OK, so the next question is, if the descriptor is going to be closed by } > some external library (again I refer to db_gdbm.c), how should the } > module mark it as no longer used in fdtable? Poke FDT_UNUSED directly? } } I guess so, it's just the rest of zclose() apart from the close itself. So this then. diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index 76d4751..0329632 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -106,7 +106,9 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func)) } dbf = gdbm_open(resource_name, 0, read_write, 0666, 0); - if(!dbf) { + if(dbf) + addmodulefd(gdbm_fdesc(dbf), FDT_INTERNAL); + else { zwarnnam(nam, "error opening database file %s", resource_name); return 1; } @@ -114,6 +116,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func)) if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, pmflags))) { zwarnnam(nam, "cannot create the requested parameter %s", pmname); + fdtable[gdbm_fdesc(dbf)] = FDT_UNUSED; gdbm_close(dbf); return 1; } @@ -319,8 +322,10 @@ gdbmuntie(Param pm) GDBM_FILE dbf = (GDBM_FILE)(pm->u.hash->tmpdata); HashTable ht = pm->u.hash; - if (dbf) /* paranoia */ + if (dbf) { /* paranoia */ + fdtable[gdbm_fdesc(dbf)] = FDT_UNUSED; gdbm_close(dbf); + } ht->tmpdata = NULL; ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-10-26 1:15 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-10-16 0:22 Mangement of fdtable[] Bart Schaefer 2015-10-16 9:56 ` Chi Hsuan Yen 2015-10-16 19:44 ` Peter Stephenson 2015-10-24 18:16 ` Peter Stephenson 2015-10-24 18:43 ` Bart Schaefer 2015-10-24 19:14 ` Peter Stephenson 2015-10-24 19:37 ` Bart Schaefer 2015-10-24 19:43 ` Peter Stephenson 2015-10-24 21:05 ` Bart Schaefer 2015-10-25 18:44 ` Peter Stephenson 2015-10-26 1:15 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).