1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-18 15:21:16 +02:00

36944: extend fd management to zsocket

This commit is contained in:
Peter Stephenson 2015-10-24 20:48:47 +01:00
parent 1f6dcf9bcd
commit 15490398d7
5 changed files with 41 additions and 14 deletions

View file

@ -1,5 +1,9 @@
2015-10-24 Peter Stephenson <p.w.stephenson@ntlworld.com> 2015-10-24 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 36944: Src/utils.c, Src/Modules/tcp.c, Src/Modules/socket.c:
extend the previous to zsocket, although this needs to allow the
fd to be closed explicitly.
* 36941: Src/utils.c, Src/zsh.h, Src/Modules/tcp.c: ensure shell * 36941: Src/utils.c, Src/zsh.h, Src/Modules/tcp.c: ensure shell
knows about file descriptiors used by ztcp and allow such file knows about file descriptiors used by ztcp and allow such file
descriptors to be marked as internal if needed (not yet used). descriptors to be marked as internal if needed (not yet used).

View file

@ -28,6 +28,11 @@ will be taken as the target file descriptor for the
connection. connection.
In order to elicit more verbose output, use tt(-v). 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() enditem()

View file

@ -115,6 +115,8 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
return 1; return 1;
} }
addmodulefd(sfd, FDT_EXTERNAL);
if (targetfd) { if (targetfd) {
sfd = redup(sfd, targetfd); sfd = redup(sfd, targetfd);
} }
@ -127,6 +129,9 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
return 1; return 1;
} }
/* allow to be closed explicitly */
fdtable[sfd] = FDT_EXTERNAL;
setiparam("REPLY", sfd); setiparam("REPLY", sfd);
if (verbose) if (verbose)
@ -200,12 +205,16 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
return 1; return 1;
} }
addmodulefd(rfd, FDT_EXTERNAL);
if (targetfd) { if (targetfd) {
sfd = redup(rfd, targetfd); sfd = redup(rfd, targetfd);
if (sfd < 0) { if (sfd < 0) {
zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno); zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
zclose(rfd);
return 1; return 1;
} }
fdtable[sfd] = FDT_EXTERNAL;
} }
else { else {
sfd = rfd; sfd = rfd;
@ -240,12 +249,16 @@ bin_zsocket(char *nam, char **args, Options ops, UNUSED(int func))
} }
else else
{ {
addmodulefd(sfd, FDT_EXTERNAL);
if (targetfd) { if (targetfd) {
sfd = redup(sfd, targetfd); if (redup(sfd, targetfd) < 0) {
if (sfd < 0) {
zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno); zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
zclose(sfd);
return 1; return 1;
} }
sfd = targetfd;
fdtable[sfd] = FDT_EXTERNAL;
} }
setiparam("REPLY", sfd); setiparam("REPLY", sfd);

View file

@ -237,7 +237,7 @@ tcp_socket(int domain, int type, int protocol, int ztflags)
sess->fd = socket(domain, type, protocol); sess->fd = socket(domain, type, protocol);
/* We'll check failure and tidy up in caller */ /* We'll check failure and tidy up in caller */
addmodulefd(sess->fd, FALSE); addmodulefd(sess->fd, FDT_MODULE);
return sess; return sess;
} }
@ -549,7 +549,7 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
} }
/* redup expects fd is already registered */ /* redup expects fd is already registered */
addmodulefd(rfd, FALSE); addmodulefd(rfd, FDT_MODULE);
if (targetfd) { if (targetfd) {
sess->fd = redup(rfd, targetfd); sess->fd = redup(rfd, targetfd);

View file

@ -1894,24 +1894,29 @@ redup(int x, int y)
/* /*
* Add an fd opened ithin a module. * Add an fd opened ithin a module.
* *
* If is_internal is FALSE, the fd can be used within the shell for * fdt is the type of the fd; see the FDT_ definitions in zsh.h.
* normal I/O but it will not be closed automatically or by normal shell * The most likely falures are:
* syntax; it can only be closed by the module (which should included *
* zclose() as part of the sequence). * 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. * Safe if fd is -1 to indicate failure.
*/ */
/**/ /**/
mod_export void mod_export void
addmodulefd(int fd, bool is_internal) addmodulefd(int fd, int fdt)
{ {
if (fd >= 0) { if (fd >= 0) {
check_fd_table(fd); check_fd_table(fd);
fdtable[fd] = is_internal ? FDT_INTERNAL : FDT_MODULE; fdtable[fd] = fdt;
} }
} }