diff options
| author | Mikael Magnusson <mikachu@gmail.com> | 2026-05-13 13:47:43 +0200 |
|---|---|---|
| committer | Mikael Magnusson <mikachu@gmail.com> | 2026-05-16 18:28:32 +0200 |
| commit | 17185544f8cf76fb5ed8215524bc03da246c5b4f (patch) | |
| tree | 6e22416535ccb3f00245f21d0656d3619f08195d /Src/Modules | |
| parent | 54565: watch: increase a quite tight bound on format length (diff) | |
| download | zsh-17185544f8cf76fb5ed8215524bc03da246c5b4f.tar zsh-17185544f8cf76fb5ed8215524bc03da246c5b4f.tar.gz zsh-17185544f8cf76fb5ed8215524bc03da246c5b4f.tar.bz2 zsh-17185544f8cf76fb5ed8215524bc03da246c5b4f.tar.lz zsh-17185544f8cf76fb5ed8215524bc03da246c5b4f.tar.xz zsh-17185544f8cf76fb5ed8215524bc03da246c5b4f.tar.zst zsh-17185544f8cf76fb5ed8215524bc03da246c5b4f.zip | |
54566: zpty: fix some issues
checkptycmd would sign extend a 0xff byte to -1, causing the byte to be
dropped, read into an unsigned char instead
the "last despairing effort" code read directly into the int, which
would probably not work on big endian. read into a temporary unsigned
char instead
the FIONREAD path used a totally undeclared variable "val", declare it,
and also initialize pollret to -1 for this path
the USE_CYGWIN_FIX path error message would always report -1 as the fd
it was unable to duplicate, report the original fd instead
initial read before the main loop in ptyread forgot to metafy the byte
avoid calling malloc with 0 length as this may be misinterpreted as oom
don't try to open sfd if opening mfd failed
Diffstat (limited to 'Src/Modules')
| -rw-r--r-- | Src/Modules/zpty.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c index b766865dd..d87e32744 100644 --- a/Src/Modules/zpty.c +++ b/Src/Modules/zpty.c @@ -292,6 +292,7 @@ get_pty(int master, int *retfd) } } } + return 1; /* don't try to open a slave if we got no master */ } name[5] = 't'; if ((sfd = open(name, O_RDWR|O_NOCTTY)) >= 0) { @@ -436,12 +437,15 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock) zexit(lastval, ZEXIT_NORMAL); } #ifndef USE_CYGWIN_FIX - master = movefd(master); - if (master == -1) { - zerrnam(nam, "cannot duplicate fd %d: %e", master, errno); - scriptname = oscriptname; - ineval = oineval; - return 1; + { + int orig_master = master; + master = movefd(master); + if (master == -1) { + zerrnam(nam, "cannot duplicate fd %d: %e", orig_master, errno); + scriptname = oscriptname; + ineval = oineval; + return 1; + } } #else addmodulefd(master, FDT_INTERNAL); @@ -529,7 +533,7 @@ deleteallptycmds(void) static void checkptycmd(Ptycmd cmd) { - char c; + unsigned char c; int r; if (cmd->read != -1 || cmd->fin) @@ -581,14 +585,19 @@ ptyread(char *nam, Ptycmd cmd, char **args, int noblock, int mustmatch) buf = (char *) zhalloc((blen = 256) + 1); } if (cmd->read != -1) { - buf[used] = (char) cmd->read; - buf[used + 1] = '\0'; - seen = used = 1; + int readchar = cmd->read; cmd->read = -1; + if (imeta(readchar)) { + buf[used++] = Meta; + buf[used++] = (char) (readchar ^ 32); + } else + buf[used++] = (char) readchar; + buf[used] = '\0'; + seen = 1; } do { if (noblock && cmd->read == -1) { - int pollret; + int pollret = -1; /* * Check there is data available. Borrowed from * poll_read() in utils.c and simplified. @@ -604,6 +613,7 @@ ptyread(char *nam, Ptycmd cmd, char **args, int noblock, int mustmatch) (SELECT_ARG_2_T) &foofd, NULL, NULL, &expire_tv); #else #ifdef FIONREAD + int val; if (ioctl(cmd->fd, FIONREAD, (char *) &val) == 0) pollret = (val > 0); #endif @@ -617,9 +627,13 @@ ptyread(char *nam, Ptycmd cmd, char **args, int noblock, int mustmatch) * character. cmd->read stores the character read. */ long mode; + unsigned char c; - if (setblock_fd(0, cmd->fd, &mode)) - pollret = read(cmd->fd, &cmd->read, 1); + if (setblock_fd(0, cmd->fd, &mode)) { + pollret = read(cmd->fd, &c, 1); + if (pollret == 1) + cmd->read = (int) c; + } if (mode != -1) fcntl(cmd->fd, F_SETFL, mode); } @@ -688,8 +702,10 @@ ptyread(char *nam, Ptycmd cmd, char **args, int noblock, int mustmatch) #endif #endif ) { - cmd->old = (char *) zalloc(cmd->olen = used); - memcpy(cmd->old, buf, cmd->olen); + if (used) { + cmd->old = (char *) zalloc(cmd->olen = used); + memcpy(cmd->old, buf, cmd->olen); + } if (prog) freepatprog(prog); |
