zsh-workers
 help / color / mirror / code / Atom feed
* [Bug] $jobstates does not work in $()
@ 2022-03-01  0:46 Carl Agrell
  2022-03-01 10:40 ` Peter Stephenson
  0 siblings, 1 reply; 11+ messages in thread
From: Carl Agrell @ 2022-03-01  0:46 UTC (permalink / raw)
  To: zsh-workers

It appears that zsh/parameter's $jobstates is always empty inside $(),
probably because it's a subshell of some sort. `jobs` still works
however, making it rather incongruous. Having access to $jobstates
would be useful for prompts for example, rather than having to parse
the output of `jobs`.

To reproduce:
❯ sleep 1000 &
[1] 210460
❯ jobs
[1]  + running    sleep 1000
❯ echo $jobstates
running:+:210460=running
❯ echo $(jobs)
[1] + running sleep 1000
❯ echo $(echo $jobstates)
(empty)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-01  0:46 [Bug] $jobstates does not work in $() Carl Agrell
@ 2022-03-01 10:40 ` Peter Stephenson
  2022-03-02  9:44   ` Daniel Shahaf
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Stephenson @ 2022-03-01 10:40 UTC (permalink / raw)
  To: Carl Agrell, zsh-workers


> On 01 March 2022 at 00:46 Carl Agrell <caagr98@gmail.com> wrote:
> 
> 
> It appears that zsh/parameter's $jobstates is always empty inside $(),
> probably because it's a subshell of some sort. `jobs` still works
> however, making it rather incongruous. Having access to $jobstates
> would be useful for prompts for example, rather than having to parse
> the output of `jobs`.
> 
> To reproduce:
> ❯ sleep 1000 &
> [1] 210460
> ❯ jobs
> [1]  + running    sleep 1000
> ❯ echo $jobstates
> running:+:210460=running
> ❯ echo $(jobs)
> [1] + running sleep 1000
> ❯ echo $(echo $jobstates)
> (empty)

Yes, we store the old job table for use with the builtin, but not with
parameters, which is inconsistent.

What is probably worse is that some parameters (not, as it happens,
jobstates) call getjob(), which does have the logic to switch to the old
table, but then make no attempt to switch to the right table for the
remainder of the processing, which could result in undefined behaviour.

This fixes it up with a function selectjobtab() used to query job states
in the parameter functions as well as getjob().

pws

--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -1244,19 +1244,19 @@ histwgetfn(UNUSED(Param pm))
 
 /**/
 static char *
-pmjobtext(int job)
+pmjobtext(Job jtab, int job)
 {
     Process pn;
     int len = 1;
     char *ret;
 
-    for (pn = jobtab[job].procs; pn; pn = pn->next)
+    for (pn = jtab[job].procs; pn; pn = pn->next)
 	len += strlen(pn->text) + 3;
 
     ret = (char *) zhalloc(len);
     ret[0] = '\0';
 
-    for (pn = jobtab[job].procs; pn; pn = pn->next) {
+    for (pn = jtab[job].procs; pn; pn = pn->next) {
 	strcat(ret, pn->text);
 	if (pn->next)
 	    strcat(ret, " | ");
@@ -1269,22 +1269,25 @@ static HashNode
 getpmjobtext(UNUSED(HashTable ht), const char *name)
 {
     Param pm = NULL;
-    int job;
+    int job, jmax;
     char *pend;
+    Job jtab;
 
     pm = (Param) hcalloc(sizeof(struct param));
     pm->node.nam = dupstring(name);
     pm->node.flags = PM_SCALAR | PM_READONLY;
     pm->gsu.s = &nullsetscalar_gsu;
 
+    selectjobtab(&jtab, &jmax);
+
     job = strtod(name, &pend);
     /* Non-numeric keys are looked up by job name */
     if (*pend)
 	job = getjob(name, NULL);
-    if (job >= 1 && job <= maxjob &&
-	jobtab[job].stat && jobtab[job].procs &&
-	!(jobtab[job].stat & STAT_NOPRINT))
-	pm->u.str = pmjobtext(job);
+    if (job >= 1 && job <= jmax &&
+	jtab[job].stat && jtab[job].procs &&
+	!(jtab[job].stat & STAT_NOPRINT))
+	pm->u.str = pmjobtext(jtab, job);
     else {
 	pm->u.str = dupstring("");
 	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
@@ -1297,22 +1300,25 @@ static void
 scanpmjobtexts(UNUSED(HashTable ht), ScanFunc func, int flags)
 {
     struct param pm;
-    int job;
+    int job, jmax;
     char buf[40];
+    Job jtab;
 
     memset((void *)&pm, 0, sizeof(struct param));
     pm.node.flags = PM_SCALAR | PM_READONLY;
     pm.gsu.s = &nullsetscalar_gsu;
 
-    for (job = 1; job <= maxjob; job++) {
-	if (jobtab[job].stat && jobtab[job].procs &&
-	    !(jobtab[job].stat & STAT_NOPRINT)) {
+    selectjobtab(&jtab, &jmax);
+
+    for (job = 1; job <= jmax; job++) {
+	if (jtab[job].stat && jtab[job].procs &&
+	    !(jtab[job].stat & STAT_NOPRINT)) {
 	    if (func != scancountparams) {
 		sprintf(buf, "%d", job);
 		pm.node.nam = dupstring(buf);
 		if ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
 		    !(flags & SCANPM_WANTKEYS))
-		    pm.u.str = pmjobtext(job);
+		    pm.u.str = pmjobtext(jtab, job);
 	    }
 	    func(&pm.node, flags);
 	}
@@ -1323,7 +1329,7 @@ scanpmjobtexts(UNUSED(HashTable ht), ScanFunc func, int flags)
 
 /**/
 static char *
-pmjobstate(int job)
+pmjobstate(Job jtab, int job)
 {
     Process pn;
     char buf[256], buf2[128], *ret, *state, *cp;
@@ -1335,14 +1341,14 @@ pmjobstate(int job)
     else
 	cp = ":";
 
-    if (jobtab[job].stat & STAT_DONE)
+    if (jtab[job].stat & STAT_DONE)
 	ret = dyncat("done", cp);
-    else if (jobtab[job].stat & STAT_STOPPED)
+    else if (jtab[job].stat & STAT_STOPPED)
 	ret = dyncat("suspended", cp);
     else
 	ret = dyncat("running", cp);
 
-    for (pn = jobtab[job].procs; pn; pn = pn->next) {
+    for (pn = jtab[job].procs; pn; pn = pn->next) {
 
 	if (pn->status == SP_RUNNING)
 	    state = "running";
@@ -1371,21 +1377,24 @@ static HashNode
 getpmjobstate(UNUSED(HashTable ht), const char *name)
 {
     Param pm = NULL;
-    int job;
+    int job, jmax;
     char *pend;
+    Job jtab;
 
     pm = (Param) hcalloc(sizeof(struct param));
     pm->node.nam = dupstring(name);
     pm->node.flags = PM_SCALAR | PM_READONLY;
     pm->gsu.s = &nullsetscalar_gsu;
 
+    selectjobtab(&jtab, &jmax);
+
     job = strtod(name, &pend);
     if (*pend)
 	job = getjob(name, NULL);
-    if (job >= 1 && job <= maxjob &&
-	jobtab[job].stat && jobtab[job].procs &&
-	!(jobtab[job].stat & STAT_NOPRINT))
-	pm->u.str = pmjobstate(job);
+    if (job >= 1 && job <= jmax &&
+	jtab[job].stat && jtab[job].procs &&
+	!(jtab[job].stat & STAT_NOPRINT))
+	pm->u.str = pmjobstate(jtab, job);
     else {
 	pm->u.str = dupstring("");
 	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
@@ -1398,22 +1407,25 @@ static void
 scanpmjobstates(UNUSED(HashTable ht), ScanFunc func, int flags)
 {
     struct param pm;
-    int job;
+    int job, jmax;
+    Job jtab;
     char buf[40];
 
+    selectjobtab(&jtab, &jmax);
+
     memset((void *)&pm, 0, sizeof(struct param));
     pm.node.flags = PM_SCALAR | PM_READONLY;
     pm.gsu.s = &nullsetscalar_gsu;
 
-    for (job = 1; job <= maxjob; job++) {
-	if (jobtab[job].stat && jobtab[job].procs &&
-	    !(jobtab[job].stat & STAT_NOPRINT)) {
+    for (job = 1; job <= jmax; job++) {
+	if (jtab[job].stat && jtab[job].procs &&
+	    !(jtab[job].stat & STAT_NOPRINT)) {
 	    if (func != scancountparams) {
 		sprintf(buf, "%d", job);
 		pm.node.nam = dupstring(buf);
 		if ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
 		    !(flags & SCANPM_WANTKEYS))
-		    pm.u.str = pmjobstate(job);
+		    pm.u.str = pmjobstate(jtab, job);
 	    }
 	    func(&pm.node, flags);
 	}
@@ -1424,11 +1436,11 @@ scanpmjobstates(UNUSED(HashTable ht), ScanFunc func, int flags)
 
 /**/
 static char *
-pmjobdir(int job)
+pmjobdir(Job jtab, int job)
 {
     char *ret;
 
-    ret = dupstring(jobtab[job].pwd ? jobtab[job].pwd : pwd);
+    ret = dupstring(jtab[job].pwd ? jtab[job].pwd : pwd);
     return ret;
 }
 
@@ -1437,21 +1449,24 @@ static HashNode
 getpmjobdir(UNUSED(HashTable ht), const char *name)
 {
     Param pm = NULL;
-    int job;
+    int job, jmax;
     char *pend;
+    Job jtab;
 
     pm = (Param) hcalloc(sizeof(struct param));
     pm->node.nam = dupstring(name);
     pm->node.flags = PM_SCALAR | PM_READONLY;
     pm->gsu.s = &nullsetscalar_gsu;
 
+    selectjobtab(&jtab, &jmax);
+
     job = strtod(name, &pend);
     if (*pend)
 	job = getjob(name, NULL);
-    if (job >= 1 && job <= maxjob &&
-	jobtab[job].stat && jobtab[job].procs &&
-	!(jobtab[job].stat & STAT_NOPRINT))
-	pm->u.str = pmjobdir(job);
+    if (job >= 1 && job <= jmax &&
+	jtab[job].stat && jtab[job].procs &&
+	!(jtab[job].stat & STAT_NOPRINT))
+	pm->u.str = pmjobdir(jtab, job);
     else {
 	pm->u.str = dupstring("");
 	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
@@ -1464,22 +1479,25 @@ static void
 scanpmjobdirs(UNUSED(HashTable ht), ScanFunc func, int flags)
 {
     struct param pm;
-    int job;
+    int job, jmax;
     char buf[40];
+    Job jtab;
 
     memset((void *)&pm, 0, sizeof(struct param));
     pm.node.flags = PM_SCALAR | PM_READONLY;
     pm.gsu.s = &nullsetscalar_gsu;
 
-    for (job = 1; job <= maxjob; job++) {
-       if (jobtab[job].stat && jobtab[job].procs &&
-           !(jobtab[job].stat & STAT_NOPRINT)) {
+    selectjobtab(&jtab, &jmax);
+
+    for (job = 1; job <= jmax; job++) {
+       if (jtab[job].stat && jtab[job].procs &&
+           !(jtab[job].stat & STAT_NOPRINT)) {
            if (func != scancountparams) {
 	       sprintf(buf, "%d", job);
 	       pm.node.nam = dupstring(buf);
                if ((flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)) ||
 		   !(flags & SCANPM_WANTKEYS))
-		   pm.u.str = pmjobdir(job);
+		   pm.u.str = pmjobdir(jtab, job);
 	   }
            func(&pm.node, flags);
        }
diff --git a/Src/jobs.c b/Src/jobs.c
index f0b337110..18e43f03c 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -98,10 +98,12 @@ mod_export int jobtabsize;
 mod_export int maxjob;
 
 /* If we have entered a subshell, the original shell's job table. */
-static struct job *oldjobtab;
+/**/
+mod_export struct job *oldjobtab;
 
 /* The size of that. */
-static int oldmaxjob;
+/**/
+mod_export int oldmaxjob;
 
 /* shell timings */
  
@@ -1894,6 +1896,26 @@ setcurjob(void)
     }
 }
 
+/* Find the job table for reporting jobs */
+
+/**/
+mod_export void
+selectjobtab(Job *jtabp, int *jmaxp)
+{
+    if (oldjobtab)
+    {
+	/* In subshell --- use saved job table to report */
+	*jtabp = oldjobtab;
+	*jmaxp = oldmaxjob;
+    }
+    else
+    {
+	/* Use main job table */
+	*jtabp = jobtab;
+	*jmaxp = maxjob;
+    }
+}
+
 /* Convert a job specifier ("%%", "%1", "%foo", "%?bar?", etc.) *
  * to a job number.                                             */
 
@@ -1904,13 +1926,7 @@ getjob(const char *s, const char *prog)
     int jobnum, returnval, mymaxjob;
     Job myjobtab;
 
-    if (oldjobtab) {
-	myjobtab = oldjobtab;
-	mymaxjob = oldmaxjob;
-    } else {
-	myjobtab= jobtab;
-	mymaxjob = maxjob;
-    }
+    selectjobtab(&myjobtab, &mymaxjob);
 
     /* if there is no %, treat as a name */
     if (*s != '%')


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-01 10:40 ` Peter Stephenson
@ 2022-03-02  9:44   ` Daniel Shahaf
  2022-03-02 20:18     ` Peter Stephenson
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Shahaf @ 2022-03-02  9:44 UTC (permalink / raw)
  To: zsh-workers; +Cc: Carl Agrell

Peter Stephenson wrote on Tue, 01 Mar 2022 10:40 +00:00:
>> On 01 March 2022 at 00:46 Carl Agrell <caagr98@gmail.com> wrote:
>> 
>> 
>> It appears that zsh/parameter's $jobstates is always empty inside $(),
>> probably because it's a subshell of some sort. `jobs` still works
>> however, making it rather incongruous. Having access to $jobstates
>> would be useful for prompts for example, rather than having to parse
>> the output of `jobs`.
>> 
>> To reproduce:
>> ❯ sleep 1000 &
>> [1] 210460
>> ❯ jobs
>> [1]  + running    sleep 1000
>> ❯ echo $jobstates
>> running:+:210460=running
>> ❯ echo $(jobs)
>> [1] + running sleep 1000
>> ❯ echo $(echo $jobstates)
>> (empty)
>
> Yes, we store the old job table for use with the builtin, but not with
> parameters, which is inconsistent.
>
> What is probably worse is that some parameters (not, as it happens,
> jobstates) call getjob(), which does have the logic to switch to the old
> table, but then make no attempt to switch to the right table for the
> remainder of the processing, which could result in undefined behaviour.
>
> This fixes it up with a function selectjobtab() used to query job states
> in the parameter functions as well as getjob().
>

Is this testable?  Sorry, haven't got time to write a test myself right now.

Cheers,

Daniel

> --- a/Src/Modules/parameter.c
> +++ b/Src/Modules/parameter.c
> @@ -1244,19 +1244,19 @@ histwgetfn(UNUSED(Param pm))
> @@ -1269,22 +1269,25 @@ static HashNode
> @@ -1297,22 +1300,25 @@ static void
> @@ -1323,7 +1329,7 @@ scanpmjobtexts(UNUSED(HashTable ht), ScanFunc 
> @@ -1335,14 +1341,14 @@ pmjobstate(int job)
> @@ -1371,21 +1377,24 @@ static HashNode
> @@ -1398,22 +1407,25 @@ static void
> @@ -1424,11 +1436,11 @@ scanpmjobstates(UNUSED(HashTable ht), ScanFunc 
> @@ -1437,21 +1449,24 @@ static HashNode
> @@ -1464,22 +1479,25 @@ static void
> --- a/Src/jobs.c
> +++ b/Src/jobs.c
> @@ -98,10 +98,12 @@ mod_export int jobtabsize;
> @@ -1894,6 +1896,26 @@ setcurjob(void)
> @@ -1904,13 +1926,7 @@ getjob(const char *s, const char *prog)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-02  9:44   ` Daniel Shahaf
@ 2022-03-02 20:18     ` Peter Stephenson
  2022-03-03 22:04       ` Vin Shelton
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Stephenson @ 2022-03-02 20:18 UTC (permalink / raw)
  To: zsh-workers

On Wed, 2022-03-02 at 09:44 +0000, Daniel Shahaf wrote:
> Peter Stephenson wrote on Tue, 01 Mar 2022 10:40 +00:00:
> Is this testable?  Sorry, haven't got time to write a test myself right now.

We could do something like this.

pws

diff --git a/Test/W02jobs.ztst b/Test/W02jobs.ztst
index b09f2ac62..d52888dd9 100644
--- a/Test/W02jobs.ztst
+++ b/Test/W02jobs.ztst
@@ -144,12 +144,14 @@
   zpty_start
   zpty_input 'sleep 3 &'
   zpty_input 'jobs -r'
+  zpty_input '(jobs -r)'
   zpty_input 'print -- -'
   zpty_input 'jobs -s'
   zpty_stop
 0:`jobs -r` and `jobs -s` with running job
 *>\[1] [0-9]##
 *>\[1]  + running*sleep*
+*>\[1]  + running*sleep*
 *>-
 *>zsh:*SIGHUPed*
 
diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
new file mode 100644
index 000000000..474adfaec
--- /dev/null
+++ b/Test/W03jobparameters.ztst
@@ -0,0 +1,49 @@
+# Tests for interactive job control with parameter state
+
+%prep
+
+  if zmodload zsh/zpty 2> /dev/null; then
+    zpty_start() {
+      export PS1= PS2=
+      zpty -d
+      zpty zsh "${(q)ZTST_testdir}/../Src/zsh -fiV +Z"
+    }
+    zpty_input() {
+      zpty -w zsh "${(F)@}" $'\n'
+    }
+    zpty_line() {
+      local REPLY
+      integer i
+      for (( i = 0; i < ${1:-1}; ++i )); do
+        zpty -r zsh REPLY
+        print -r -- ${REPLY%%($'\r\n'|$'\n')}
+      done
+    }
+    zpty_stop() {
+      # exit twice in case of check_jobs
+      zpty -w zsh $'exit\nexit\n'
+      # zpty gives no output when piped without these braces (?)
+      { zpty -r zsh } | sed $'/[^[:space:]]/!d; s/\r$//;'
+      zpty -d
+      :
+    }
+    if ! zmodload zsh/parameter 2> /dev/null; then
+      ZTST_unimplemented='the zsh/parameter module is not available'
+    fi
+  else
+    ZTST_unimplemented='the zsh/zpty module is not available'
+  fi
+
+%test
+
+  zpty_start
+  zpty_input 'sleep 3 &'
+  zpty_input 'print $jobstates'
+  zpty_input '(print $jobstates)'
+  zpty_input 'jobs -s'
+  zpty_stop
+0:$jobstate for running job in main shell and subshell
+*>\[1] [0-9]##
+*>running:+:*=running
+*>running:+:*=running
+*>zsh:*SIGHUPed*



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-02 20:18     ` Peter Stephenson
@ 2022-03-03 22:04       ` Vin Shelton
  2022-03-03 23:07         ` Bart Schaefer
  0 siblings, 1 reply; 11+ messages in thread
From: Vin Shelton @ 2022-03-03 22:04 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 6782 bytes --]

I don't see how you could have provoked this, Peter, but in the latest
sources, I'm seeing a test failure under i3 in Arch:

ZTST_verbose=2 make TESTNUM=W03 check
cd Test ; make check
make[1]: Entering directory '/opt/build/zsh-2022-03-03/Test'
if test -n "gcc"; then \
  cd .. && DESTDIR= \
  make MODDIR=`pwd`/Test/Modules install.modules > /dev/null; \
fi
if test -z "$ZTST_handler"; then \
  ZTST_handler=runtests.zsh; \
fi; \
if ZTST_testlist="`for f in ../../../src/zsh-2022-03-03/Test/W03*.ztst; \
           do echo $f; done`" \
 ZTST_srcdir="../../../src/zsh-2022-03-03/Test" \
 ZTST_exe=../Src/zsh \
 ../Src/zsh +Z -f ../../../src/zsh-2022-03-03/Test/$ZTST_handler; then \
 stat=0; \
else \
 stat=1; \
fi; \
sleep 1; \
rm -rf Modules .zcompdump; \
exit $stat
../../../src/zsh-2022-03-03/Test/W03jobparameters.ztst: starting.
ZTST_getsect: read section name: prep
ZTST_getchunk: read code chunk:
  if zmodload zsh/zpty 2> /dev/null; then
    zpty_start() {
      export PS1= PS2=
      zpty -d
      zpty zsh "${(q)ZTST_testdir}/../Src/zsh -fiV +Z"
    }
    zpty_input() {
      zpty -w zsh "${(F)@}" $'\n'
    }
    zpty_line() {
      local REPLY
      integer i
      for (( i = 0; i < ${1:-1}; ++i )); do
        zpty -r zsh REPLY
        print -r -- ${REPLY%%($'\r\n'|$'\n')}
      done
    }
    zpty_stop() {
      # exit twice in case of check_jobs
      zpty -w zsh $'exit\nexit\n'
      # zpty gives no output when piped without these braces (?)
      { zpty -r zsh } | sed $'/[^[:space:]]/!d; s/\r$//;'
      zpty -d
      :
    }
    if ! zmodload zsh/parameter 2> /dev/null; then
      ZTST_unimplemented='the zsh/parameter module is not available'
    fi
  else
    ZTST_unimplemented='the zsh/zpty module is not available'
  fi
ZTST_execchunk: status 0
ZTST_getchunk: read code chunk:

ZTST_getsect: read section name: test
ZTST_test: looking for new test
ZTST_test: examining line:

ZTST_test: examining line:
  zpty_start
ZTST_getchunk: read code chunk:
  zpty_start
  zpty_input 'sleep 3 &'
  zpty_input 'print $jobstates'
  zpty_input '(print $jobstates)'
  zpty_input 'jobs -s'
  zpty_stop
ZTST_test: examining line:
*>\[1] [0-9]##
ZTST_getredir: read redir for '>':
\[1] [0-9]##
ZTST_test: examining line:
*>running:+:*=running
ZTST_getredir: read redir for '>':
running:+:*=running
ZTST_test: examining line:
*>running:+:*=running
ZTST_getredir: read redir for '>':
running:+:*=running
ZTST_test: examining line:
*>zsh:*SIGHUPed*
ZTST_getredir: read redir for '>':
zsh:*SIGHUPed*
ZTST_test: examining line:

Running test: $jobstate for running job in main shell and subshell
ZTST_test: expecting status: 0
Input: /tmp/zsh.ztst.46005/ztst.in, output: /tmp/zsh.ztst.46005/ztst.out,
error: /tmp/zsh.ztst.46005/ztst.terr
ZTST_execchunk: status 0
ZTST_test: test produced standard output:
[1] 46016
zsh: failed to load module `zsh/parameter':
/opt/zsh-2022-03-03/lib/zsh/5.8.1.1-dev/zsh/parameter.so: cannot open
shared object file: No such file or directory
zsh/parameter
zsh: failed to load module `zsh/parameter':
/opt/zsh-2022-03-03/lib/zsh/5.8.1.1-dev/zsh/parameter.so: cannot open
shared object file: No such file or directory
zsh/parameter
zsh: warning: 1 jobs SIGHUPed
ZTST_test: and standard error:

Pattern match failed, line mismatch (4/6):
 <\[1] [0-9]##
 <running:+:*=running
 <running:+:*=running
 <zsh:*SIGHUPed*
 >[1] 46016
 >zsh: failed to load module `zsh/parameter':
/opt/zsh-2022-03-03/lib/zsh/5.8.1.1-dev/zsh/parameter.so: cannot open
shared object file: No such file or directory
 >zsh/parameter
 >zsh: failed to load module `zsh/parameter':
/opt/zsh-2022-03-03/lib/zsh/5.8.1.1-dev/zsh/parameter.so: cannot open
shared object file: No such file or directory
 >zsh/parameter
 >zsh: warning: 1 jobs SIGHUPed
Test ../../../src/zsh-2022-03-03/Test/W03jobparameters.ztst failed: output
differs from expected as shown above for:
  zpty_start
  zpty_input 'sleep 3 &'
  zpty_input 'print $jobstates'
  zpty_input '(print $jobstates)'
  zpty_input 'jobs -s'
  zpty_stop
Was testing: $jobstate for running job in main shell and subshell
../../../src/zsh-2022-03-03/Test/W03jobparameters.ztst: test failed.
**************************************
0 successful test scripts, 1 failure, 0 skipped
**************************************
make[1]: *** [Makefile:190: check] Error 1
make[1]: Leaving directory '/opt/build/zsh-2022-03-03/Test'
make: *** [Makefile:263: check] Error 2

TIA,
  Vin

On Wed, Mar 2, 2022 at 3:19 PM Peter Stephenson <p.w.stephenson@ntlworld.com>
wrote:

> On Wed, 2022-03-02 at 09:44 +0000, Daniel Shahaf wrote:
> > Peter Stephenson wrote on Tue, 01 Mar 2022 10:40 +00:00:
> > Is this testable?  Sorry, haven't got time to write a test myself right
> now.
>
> We could do something like this.
>
> pws
>
> diff --git a/Test/W02jobs.ztst b/Test/W02jobs.ztst
> index b09f2ac62..d52888dd9 100644
> --- a/Test/W02jobs.ztst
> +++ b/Test/W02jobs.ztst
> @@ -144,12 +144,14 @@
>    zpty_start
>    zpty_input 'sleep 3 &'
>    zpty_input 'jobs -r'
> +  zpty_input '(jobs -r)'
>    zpty_input 'print -- -'
>    zpty_input 'jobs -s'
>    zpty_stop
>  0:`jobs -r` and `jobs -s` with running job
>  *>\[1] [0-9]##
>  *>\[1]  + running*sleep*
> +*>\[1]  + running*sleep*
>  *>-
>  *>zsh:*SIGHUPed*
>
> diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
> new file mode 100644
> index 000000000..474adfaec
> --- /dev/null
> +++ b/Test/W03jobparameters.ztst
> @@ -0,0 +1,49 @@
> +# Tests for interactive job control with parameter state
> +
> +%prep
> +
> +  if zmodload zsh/zpty 2> /dev/null; then
> +    zpty_start() {
> +      export PS1= PS2=
> +      zpty -d
> +      zpty zsh "${(q)ZTST_testdir}/../Src/zsh -fiV +Z"
> +    }
> +    zpty_input() {
> +      zpty -w zsh "${(F)@}" $'\n'
> +    }
> +    zpty_line() {
> +      local REPLY
> +      integer i
> +      for (( i = 0; i < ${1:-1}; ++i )); do
> +        zpty -r zsh REPLY
> +        print -r -- ${REPLY%%($'\r\n'|$'\n')}
> +      done
> +    }
> +    zpty_stop() {
> +      # exit twice in case of check_jobs
> +      zpty -w zsh $'exit\nexit\n'
> +      # zpty gives no output when piped without these braces (?)
> +      { zpty -r zsh } | sed $'/[^[:space:]]/!d; s/\r$//;'
> +      zpty -d
> +      :
> +    }
> +    if ! zmodload zsh/parameter 2> /dev/null; then
> +      ZTST_unimplemented='the zsh/parameter module is not available'
> +    fi
> +  else
> +    ZTST_unimplemented='the zsh/zpty module is not available'
> +  fi
> +
> +%test
> +
> +  zpty_start
> +  zpty_input 'sleep 3 &'
> +  zpty_input 'print $jobstates'
> +  zpty_input '(print $jobstates)'
> +  zpty_input 'jobs -s'
> +  zpty_stop
> +0:$jobstate for running job in main shell and subshell
> +*>\[1] [0-9]##
> +*>running:+:*=running
> +*>running:+:*=running
> +*>zsh:*SIGHUPed*
>
>
>

[-- Attachment #2: Type: text/html, Size: 9050 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-03 22:04       ` Vin Shelton
@ 2022-03-03 23:07         ` Bart Schaefer
  2022-03-04  2:14           ` Jun T
  0 siblings, 1 reply; 11+ messages in thread
From: Bart Schaefer @ 2022-03-03 23:07 UTC (permalink / raw)
  To: Vin Shelton; +Cc: Peter Stephenson, zsh-workers

On Thu, Mar 3, 2022 at 2:05 PM Vin Shelton <acs@alumni.princeton.edu> wrote:
>
> I don't see how you could have provoked this, Peter, but in the latest sources, I'm seeing a test failure under i3 in Arch:

Try this:

diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
index 474adfaec..c0dd1e10e 100644
--- a/Test/W03jobparameters.ztst
+++ b/Test/W03jobparameters.ztst
@@ -37,6 +37,7 @@
 %test

   zpty_start
+  zpty_input 'zmodload zsh/parameter'
   zpty_input 'sleep 3 &'
   zpty_input 'print $jobstates'
   zpty_input '(print $jobstates)'


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-03 23:07         ` Bart Schaefer
@ 2022-03-04  2:14           ` Jun T
  2022-03-04 13:04             ` Daniel Shahaf
  0 siblings, 1 reply; 11+ messages in thread
From: Jun T @ 2022-03-04  2:14 UTC (permalink / raw)
  To: zsh-workers


> 2022/03/04 8:07, Bart Schaefer <schaefer@brasslantern.com> wrote:
> 
> On Thu, Mar 3, 2022 at 2:05 PM Vin Shelton <acs@alumni.princeton.edu> wrote:
>> 
>> I don't see how you could have provoked this, Peter, but in the latest sources, I'm seeing a test failure under i3 in Arch:
> 
> Try this:
> 
> diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
(snip)
> +  zpty_input 'zmodload zsh/parameter'

This doesn't work for me.

I think the problem is that MODULE_PATH is not imported by the zsh started
by zpty (for security).


diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
index 474adfaec..de3420038 100644
--- a/Test/W03jobparameters.ztst
+++ b/Test/W03jobparameters.ztst
@@ -37,6 +37,7 @@
 %test
 
   zpty_start
+  zpty_input "MODULE_PATH=$MODULE_PATH"
   zpty_input 'sleep 3 &'
   zpty_input 'print $jobstates'
   zpty_input '(print $jobstates)'



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-04  2:14           ` Jun T
@ 2022-03-04 13:04             ` Daniel Shahaf
  2022-03-04 13:13               ` Vin Shelton
  2022-03-06  4:18               ` Jun T
  0 siblings, 2 replies; 11+ messages in thread
From: Daniel Shahaf @ 2022-03-04 13:04 UTC (permalink / raw)
  To: zsh-workers

Jun T wrote on Fri, Mar 04, 2022 at 11:14:07 +0900:
> 
> > 2022/03/04 8:07, Bart Schaefer <schaefer@brasslantern.com> wrote:
> > 
> > On Thu, Mar 3, 2022 at 2:05 PM Vin Shelton <acs@alumni.princeton.edu> wrote:
> >> 
> >> I don't see how you could have provoked this, Peter, but in the latest sources, I'm seeing a test failure under i3 in Arch:
> > 
> > Try this:
> > 
> > diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
> (snip)
> > +  zpty_input 'zmodload zsh/parameter'
> 
> This doesn't work for me.
> 
> I think the problem is that MODULE_PATH is not imported by the zsh started
> by zpty (for security).
> 
> 
> diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
> index 474adfaec..de3420038 100644
> --- a/Test/W03jobparameters.ztst
> +++ b/Test/W03jobparameters.ztst
> @@ -37,6 +37,7 @@
>  %test
>  
>    zpty_start
> +  zpty_input "MODULE_PATH=$MODULE_PATH"

Add ${(q)}?

Cheers,

Daniel


>    zpty_input 'sleep 3 &'
>    zpty_input 'print $jobstates'
>    zpty_input '(print $jobstates)'
> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-04 13:04             ` Daniel Shahaf
@ 2022-03-04 13:13               ` Vin Shelton
  2022-03-06  4:18               ` Jun T
  1 sibling, 0 replies; 11+ messages in thread
From: Vin Shelton @ 2022-03-04 13:13 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Zsh Hackers' List

[-- Attachment #1: Type: text/plain, Size: 1240 bytes --]

Jun's fix is necessary for me.

  - Vin

On Fri, Mar 4, 2022 at 8:05 AM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:

> Jun T wrote on Fri, Mar 04, 2022 at 11:14:07 +0900:
> >
> > > 2022/03/04 8:07, Bart Schaefer <schaefer@brasslantern.com> wrote:
> > >
> > > On Thu, Mar 3, 2022 at 2:05 PM Vin Shelton <acs@alumni.princeton.edu>
> wrote:
> > >>
> > >> I don't see how you could have provoked this, Peter, but in the
> latest sources, I'm seeing a test failure under i3 in Arch:
> > >
> > > Try this:
> > >
> > > diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
> > (snip)
> > > +  zpty_input 'zmodload zsh/parameter'
> >
> > This doesn't work for me.
> >
> > I think the problem is that MODULE_PATH is not imported by the zsh
> started
> > by zpty (for security).
> >
> >
> > diff --git a/Test/W03jobparameters.ztst b/Test/W03jobparameters.ztst
> > index 474adfaec..de3420038 100644
> > --- a/Test/W03jobparameters.ztst
> > +++ b/Test/W03jobparameters.ztst
> > @@ -37,6 +37,7 @@
> >  %test
> >
> >    zpty_start
> > +  zpty_input "MODULE_PATH=$MODULE_PATH"
>
> Add ${(q)}?
>
> Cheers,
>
> Daniel
>
>
> >    zpty_input 'sleep 3 &'
> >    zpty_input 'print $jobstates'
> >    zpty_input '(print $jobstates)'
> >
> >
>
>

[-- Attachment #2: Type: text/html, Size: 2288 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-04 13:04             ` Daniel Shahaf
  2022-03-04 13:13               ` Vin Shelton
@ 2022-03-06  4:18               ` Jun T
  2022-03-07 14:22                 ` Daniel Shahaf
  1 sibling, 1 reply; 11+ messages in thread
From: Jun T @ 2022-03-06  4:18 UTC (permalink / raw)
  To: zsh-workers


> 2022/03/04 22:04, Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> 
> Jun T wrote on Fri, Mar 04, 2022 at 11:14:07 +0900:

>> +  zpty_input "MODULE_PATH=$MODULE_PATH"
> 
> Add ${(q)}?

OK, but if the build directory name contains spaces then
'make check' fails anyway.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Bug] $jobstates does not work in $()
  2022-03-06  4:18               ` Jun T
@ 2022-03-07 14:22                 ` Daniel Shahaf
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Shahaf @ 2022-03-07 14:22 UTC (permalink / raw)
  To: zsh-workers

Jun T wrote on Sun, 06 Mar 2022 04:18 +00:00:
>> 2022/03/04 22:04, Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>> 
>> Jun T wrote on Fri, Mar 04, 2022 at 11:14:07 +0900:
>
>>> +  zpty_input "MODULE_PATH=$MODULE_PATH"
>> 
>> Add ${(q)}?
>
> OK,

Thanks.

> but if the build directory name contains spaces then
> 'make check' fails anyway.

Even so, I think it's a good idea to use (q) there, so the code is
reusable if someone copies it to some other context with another
variable, and so readers don't wonder why the (q) isn't there.

Cheers,

Daniel


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-03-07 14:23 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-01  0:46 [Bug] $jobstates does not work in $() Carl Agrell
2022-03-01 10:40 ` Peter Stephenson
2022-03-02  9:44   ` Daniel Shahaf
2022-03-02 20:18     ` Peter Stephenson
2022-03-03 22:04       ` Vin Shelton
2022-03-03 23:07         ` Bart Schaefer
2022-03-04  2:14           ` Jun T
2022-03-04 13:04             ` Daniel Shahaf
2022-03-04 13:13               ` Vin Shelton
2022-03-06  4:18               ` Jun T
2022-03-07 14:22                 ` Daniel Shahaf

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).