pkgsrc-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[patch] shells/posh: several builtins are unusable; fix getopt(3) usage.



I don't suppose anyone has tried shells/posh on NetBSD lately :-)

Several builtins do their own option processing with getopt(3), and before re-calling getopt(3), the `optind` variable has to be set to the next `argv` index getopt(3) should look at.

When running the dot-builtin (.), e.g. ``. ./file-to-source.sh'', argv (in array initializer syntax) becomes { ".", "./file-to-source.sh" }.

posh sets optind to 0, then calls getopt(3).  getopt(3) looks at argv[optind], which is ".", and returns immediately because that isn't an option (it doesn't start with '-').
This works with GNU getopt, because of its headache-inducing property that arguments (no hyphen) may come after options (hyphen) it will proceed looking at higher indices.

However with our getopt(3), that does not work, we're "done" once we see something that doesn't start with a hypen -- optind must thus be set to 1.

It's resetting `optind` to zero (as opposed to 1) before re-calling getopt(3); the attached patch accomplishes that.


Cheers,

Timo Buhrmester


PS: I have the feeling that the attached patch should be applied against posh itself, rather than patched in pkgsrc.  Does anyone know a good reason to begin getopt(3)ing at argv[0] when using GNU getopt?

PPS: There's another instance of ``optind = 0'' in exec.c, which I am unsure about; the attached patch does NOT touch it.
|	/* We need to set optind to 0 or else +p won't work */
|	optind = 0;
|
|	while ((optc = getopt(noargc, ap, "+p")) != -1) {
|		switch (optc) {

"+p"? Is this a GNUism?
--- src/builtins.c.orig	2015-08-30 04:23:22.000000000 +0200
+++ src/builtins.c	2015-08-30 04:23:11.000000000 +0200
@@ -38,7 +38,7 @@
 	struct env *ep, *last_ep = (struct env *) 0;
 	char *arg;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "")) != -1) {
 		switch (optc) {
@@ -114,7 +114,7 @@
 	int phys_path;
 	char *cdpath;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "LP")) != -1) {
 		switch (optc) {
@@ -250,7 +250,7 @@
 	int i;
 	int err;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "")) != -1) {
 		switch (optc) {
@@ -417,7 +417,7 @@
 	int n, optc;
 	char *arg;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "")) != -1) {
 		switch (optc) {
@@ -554,7 +554,7 @@
 	if(flags & POSH_BUILTIN_READONLY)
  		fset |= RDONLY;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "p")) != -1) {
 		switch (optc) {
@@ -617,7 +617,7 @@
 	struct source *s,*olds=source;
 	int retval, optc, errexitflagtmp;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "+")) != -1) {
 		switch (optc) {
@@ -819,7 +819,7 @@
 	int optc, physical = 0;
 	char *p, **wp;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "LP")) != -1)
 		switch (optc) {
@@ -869,7 +869,7 @@
 	XString cs;
 	struct tbl *vp;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "r")) != -1)
 		switch (optc) {
@@ -1030,7 +1030,7 @@
 	long val;
 	char *arg;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "")) != -1) {
 		switch (optc) {
@@ -1066,7 +1066,7 @@
 	char *s;
 	Trap *p;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "")) != -1) {
 		switch (optc) {
@@ -1138,7 +1138,7 @@
 	int symbolic = 0;
 	int old_umask, optc, noargc;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "S")) != -1) {
 		switch (optc) {
@@ -1261,7 +1261,7 @@
 	int optc, unset_var = 1;
 	int ret = 0;
 
-	optind = 0;
+	optind = 1;
 
 	while ((optc = getopt(argc, argv, "fv")) != -1) {
 		switch(optc) {


Home | Main Index | Thread Index | Old Index