summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2005-07-01 02:11:56 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2005-07-01 02:11:56 +0000
commit64f9e6f06daae6d1e35da7f1a4f65887b99e4a10 (patch)
tree29b8975d2836fcb19547f96ee17ab34d9dfd6dea
parent90fddac1ecf803ca16f41612c08f58c63ef38720 (diff)
More robust example of numeric argument handling. The old example
code would dereference NULL for mixed letter and number args. OK deraadt@
-rw-r--r--lib/libc/stdlib/getopt.334
1 files changed, 23 insertions, 11 deletions
diff --git a/lib/libc/stdlib/getopt.3 b/lib/libc/stdlib/getopt.3
index e0dc3701f90..52c902d6a54 100644
--- a/lib/libc/stdlib/getopt.3
+++ b/lib/libc/stdlib/getopt.3
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $OpenBSD: getopt.3,v 1.31 2005/03/26 22:02:15 millert Exp $
+.\" $OpenBSD: getopt.3,v 1.32 2005/07/01 02:11:55 millert Exp $
.\"
.Dd December 17, 2002
.Dt GETOPT 3
@@ -351,22 +351,34 @@ as an option.
This practice is wrong, and should not be used in any current development.
It is provided for backward compatibility
.Em only .
-The following code fragment works in most cases.
+The following code fragment works in most cases and can handle mixed
+number and letter arguments.
+
.Bd -literal -offset indent
-int ch;
-long length;
-char *p;
+int aflag = 0, bflag = 0, ch, lastch = '\e0';
+int length = -1, newarg = 1, prevoptind = 1;
-while ((ch = getopt(argc, argv, "0123456789")) != -1) {
+while ((ch = getopt(argc, argv, "0123456789ab")) != -1) {
switch (ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- p = argv[optind - 1];
- if (p[0] == '-' && p[1] == ch && !p[2])
- length = ch - '0';
- else
- length = strtol(argv[optind] + 1, NULL, 10);
+ if (newarg || !isdigit(lastch))
+ length = 0;
+ else if (length > INT_MAX / 10)
+ usage();
+ length = (length * 10) + (ch - '0');
+ break;
+ case 'a':
+ aflag = 1;
break;
+ case 'b':
+ bflag = 1;
+ break;
+ default:
+ usage();
}
+ lastch = ch;
+ newarg = optind != prevoptind;
+ prevoptind = optind;
}
.Ed