public inbox for dash@vger.kernel.org
 help / color / mirror / Atom feed
From: Michael Greenberg <michael@greenberg.science>
To: наб <nabijaczleweli@nabijaczleweli.xyz>, dash@vger.kernel.org
Subject: Re: [PATCH] options: don't error when unsetting OPTIND
Date: Wed, 14 Dec 2022 09:18:25 -0500	[thread overview]
Message-ID: <m2edt2nk5q.fsf@greenberg.science> (raw)
In-Reply-To: <20221214023130.u7pn4ca6ma4kuxot@tarta.nabijaczleweli.xyz>

While we're thinking about it, is this the behavior we want? Or should
`readonly` produce an error?

```
$ getopts abc ARG -ab -c foo
$ echo $OPTIND
2
$ echo $ARG
a
$ readonly OPTIND
$ getopts abc ARG -ab -c foo
/Users/mgree/smoosh/libdash/src/dash: 5: getopts: OPTIND: is read only
$ echo $ARG
a
$ echo $OPTIND
2
```

There are similar questions for PWD and other shell-set nameable
variables:

```
$ readonly PWD
$ pwd
/Users/mgree/pash-medium/budgeting
$ cd ..
/Users/mgree/smoosh/libdash/src/dash: 13: cd: PWD: is read only
$ pwd
/Users/mgree/pash-medium
```

But special parameters (like @ and ?) are outright rejected by
`readonly`.

Bafflingly, the POSIX spec gives the example `readonly HOME PWD`, but
with no explanation about why one might want to do that. (I get making
`HOME` readonly, but `PWD`? Is that supposed to stop `cd` from working?)

Cheers,
Michael

On 2022-12-14 at 03:31:30 AM, наб wrote:

> unset OPTIND ends up calling getoptsreset("") which errors out with
>   sh: 1: unset: Illegal number:
> or even
>   sh: 1: unset: Illegal number: leweli/bin:/usr/l��
>
> Pass the current flags to struct var->func, set the getopts optind to 1
> and continue with allowing the unset.
>
> We still forbid OPTIND=, OPTIND=-1, OPTIND=abc, &c.
>
> Fixes: https://bugs.debian.org/985478
> ---
>  src/exec.c    | 2 +-
>  src/exec.h    | 2 +-
>  src/mail.c    | 2 +-
>  src/mail.h    | 2 +-
>  src/options.c | 5 ++---
>  src/options.h | 2 +-
>  src/var.c     | 4 ++--
>  src/var.h     | 2 +-
>  8 files changed, 10 insertions(+), 11 deletions(-)
>
> diff --git a/src/exec.c b/src/exec.c
> index 87354d4..68fa8ab 100644
> --- a/src/exec.c
> +++ b/src/exec.c
> @@ -565,7 +565,7 @@ hashcd(void)
>   */
>  
>  void
> -changepath(const char *newval)
> +changepath(const char *newval, int unused)
>  {
>  	const char *new;
>  	int idx;
> diff --git a/src/exec.h b/src/exec.h
> index 423b07e..0f74be4 100644
> --- a/src/exec.h
> +++ b/src/exec.h
> @@ -69,7 +69,7 @@ int hashcmd(int, char **);
>  void find_command(char *, struct cmdentry *, int, const char *);
>  struct builtincmd *find_builtin(const char *);
>  void hashcd(void);
> -void changepath(const char *);
> +void changepath(const char *, int);
>  #ifdef notdef
>  void getcmdentry(char *, struct cmdentry *);
>  #endif
> diff --git a/src/mail.c b/src/mail.c
> index 8eacb2d..e81d2b4 100644
> --- a/src/mail.c
> +++ b/src/mail.c
> @@ -109,7 +109,7 @@ chkmail(void)
>  
>  
>  void
> -changemail(const char *val)
> +changemail(const char *val, int unused)
>  {
>  	changed++;
>  }
> diff --git a/src/mail.h b/src/mail.h
> index 3c6b21d..70b54a4 100644
> --- a/src/mail.h
> +++ b/src/mail.h
> @@ -35,4 +35,4 @@
>   */
>  
>  void chkmail(void);
> -void changemail(const char *);
> +void changemail(const char *, int);
> diff --git a/src/options.c b/src/options.c
> index a46c23b..81f2c4b 100644
> --- a/src/options.c
> +++ b/src/options.c
> @@ -390,10 +390,9 @@ setcmd(int argc, char **argv)
>  
>  
>  void
> -getoptsreset(value)
> -	const char *value;
> +getoptsreset(const char *value, int flags)
>  {
> -	shellparam.optind = number(value) ?: 1;
> +	shellparam.optind = (flags & VUNSET) ? 1 : number(value) ?: 1;
>  	shellparam.optoff = -1;
>  }
>  
> diff --git a/src/options.h b/src/options.h
> index 975fe33..10bcb88 100644
> --- a/src/options.h
> +++ b/src/options.h
> @@ -83,4 +83,4 @@ int shiftcmd(int, char **);
>  int setcmd(int, char **);
>  int getoptscmd(int, char **);
>  int nextopt(const char *);
> -void getoptsreset(const char *);
> +void getoptsreset(const char *, int);
> diff --git a/src/var.c b/src/var.c
> index ef9c2bd..a7d4a92 100644
> --- a/src/var.c
> +++ b/src/var.c
> @@ -266,7 +266,7 @@ struct var *setvareq(char *s, int flags)
>  			goto out;
>  
>  		if (vp->func && (flags & VNOFUNC) == 0)
> -			(*vp->func)(strchrnul(s, '=') + 1);
> +			(*vp->func)(strchrnul(s, '=') + 1, flags);
>  
>  		if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
>  			ckfree(vp->text);
> @@ -531,7 +531,7 @@ poplocalvars(void)
>  			unsetvar(vp->text);
>  		} else {
>  			if (vp->func)
> -				(*vp->func)(strchrnul(lvp->text, '=') + 1);
> +				(*vp->func)(strchrnul(lvp->text, '=') + 1, lvp->flags);
>  			if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
>  				ckfree(vp->text);
>  			vp->flags = lvp->flags;
> diff --git a/src/var.h b/src/var.h
> index aa7575a..4329e22 100644
> --- a/src/var.h
> +++ b/src/var.h
> @@ -56,7 +56,7 @@ struct var {
>  	struct var *next;		/* next entry in hash list */
>  	int flags;			/* flags are defined above */
>  	const char *text;		/* name=value */
> -	void (*func)(const char *);
> +	void (*func)(const char *, int flags);
>  					/* function to be called when  */
>  					/* the variable gets set/unset */
>  };
> -- 
> 2.30.2

  reply	other threads:[~2022-12-14 14:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-14  2:31 [PATCH] options: don't error when unsetting OPTIND наб
2022-12-14 14:18 ` Michael Greenberg [this message]
2022-12-14 17:49   ` Steffen Nurpmeso
2022-12-14 22:36     ` Michael Greenberg
2022-12-14 23:07       ` наб
2022-12-15 18:39         ` Michael Greenberg
2023-01-03  9:39 ` [PATCH] var: Do not add 1 to return value of strchrnul Herbert Xu
2023-01-03  9:51   ` [v2 PATCH] " Herbert Xu
2023-01-03 12:26   ` [PATCH] " наб
2023-01-04  9:59     ` Herbert Xu
2023-01-04 12:54       ` наб
2023-01-04 14:12         ` Herbert Xu
2023-01-04 16:05           ` наб
2023-01-04 16:50             ` Harald van Dijk
2024-05-19 11:19               ` [PATCH] options: Always reset OPTIND in getoptsreset Herbert Xu
2024-05-19 13:23                 ` Harald van Dijk
2024-05-19 14:21                   ` [v2 PATCH] " Herbert Xu
2024-05-21 14:38                     ` наб

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2edt2nk5q.fsf@greenberg.science \
    --to=michael@greenberg.science \
    --cc=dash@vger.kernel.org \
    --cc=nabijaczleweli@nabijaczleweli.xyz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox