SVN: rc-scripts/trunk: man/getkey.1 src/getkey.c

arekm arekm at pld-linux.org
Fri Oct 13 08:22:43 CEST 2006


Author: arekm
Date: Fri Oct 13 08:22:42 2006
New Revision: 7851

Added:
   rc-scripts/trunk/man/getkey.1
Modified:
   rc-scripts/trunk/src/getkey.c
Log:
Updated.

Added: rc-scripts/trunk/man/getkey.1
==============================================================================
--- (empty file)
+++ rc-scripts/trunk/man/getkey.1	Fri Oct 13 08:22:42 2006
@@ -0,0 +1,80 @@
+.\" A man page for getkey(1). -*- nroff -*-
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All rights reserved.
+.\"
+.\" This copyrighted material is made available to anyone wishing to use,
+.\" modify, copy, or redistribute it subject to the terms and conditions of the
+.\" GNU General Public License v.2.
+.\"
+.\" This program is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
+.\" more details.
+.\"
+.\" You should have received a copy of the GNU General Public License along
+.\" with this program; if not, write to the Free Software Foundation, Inc.,
+.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+.\"
+.\" Author: Miloslav Trmac <mitr at redhat.com>
+.TH getkey 1 "Jan 2006"
+
+.SH NAME
+getkey \- wait until a key is pressed
+
+.SH SYNOPSIS
+\fBgetkey\fR [\fIOPTION\fR]... [\fIKEYS\fR]
+
+.SH DESCRIPTION
+.B getkey
+waits until one of
+.I KEYS
+is pressed.
+If
+.I KEYS
+are not specified, any key is accepted.
+.I KEYS
+are matched case-insensitive.
+
+.SH EXIT STATUS
+.B getkey
+exits with status 0 if one of the expected keys is pressed.
+If invalid arguments are specified,
+.B getkey
+exits with status 255.
+If
+.B getkey
+is interrupted or the wait times out,
+.B getkey
+exits with other non-zero status.
+
+.SH OPTIONS
+.TP
+\fB\-c\fR, \fB\-\-wait\fR \fISECONDS\fR
+Wait only for
+.I SECONDS
+seconds.
+The default is 0, which means to wait without a time limit.
+
+.TP
+\fB\-i\fR, \fB\-\-ignore\-control\-chars\fR
+Don't treat Ctrl+C and Ctrl+D specially.
+When this option is not specified, these characters interrupt \fBgetkey\fR.
+
+.TP
+\fB\-m\fR, \fB\-\-message\fR \fIMESSAGE\fR
+Display
+.I MESSAGE
+while waiting.
+The message is used as a format string in
+.BR sprintf (3),
+with a single argument, the number of seconds left.
+Typical usage is therefore
+\fB"Press a key within %d seconds to ..."\fR.
+If
+.I MESSAGE
+contains other format string directives, the behavior is undefined and
+.B getkey
+may crash.
+
+If there is no time limit specified,
+the number of seconds left is reported as 0.

Modified: rc-scripts/trunk/src/getkey.c
==============================================================================
--- rc-scripts/trunk/src/getkey.c	(original)
+++ rc-scripts/trunk/src/getkey.c	Fri Oct 13 08:22:42 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2003 Red Hat, Inc. All rights reserved.
+ * Copyright (c) 1999-2003, 2006 Red Hat, Inc. All rights reserved.
  *
  * This software may be freely redistributed under the terms of the GNU
  * public license.
@@ -24,37 +24,35 @@
 #include <sys/poll.h>
 #include "popt.h"
 
-struct termios tp;
+static struct termios orig_tp;
 
-void reset_term(int x) {
-	tcsetattr(0,TCSANOW,&tp);
-	exit(x);
+static void reset_term(int x) {
+	tcsetattr(0,TCSANOW,&orig_tp);
+	_exit(x);
 }
 
 int main(int argc, char **argv) {
-	char foo[2];
-	char list[100]; /* should be enough */
+        static const char default_list[] = "";
+
+	const char *list;
 	char *waitmessage = NULL;
 	char *waitprint, *waitsprint;
-	const char *fooptr;
 	int waitseconds=0;
 	int alarmlen=0;
 	int ignore_control=0;
-	int tp_if,tp_of,tp_lf;
-	int x, r;
+	struct termios tp;
+	int r;
 	struct pollfd ufds; /* only one, no need for an array... */
         poptContext context;
 	struct poptOption options[] = {
             { "wait", 'c', POPT_ARG_INT, &waitseconds, 0, "Number of seconds to wait for keypress", NULL },
-	    /*            { "message", 'm', POPT_ARG_STRING, &waitmessage, 0, "Message to print out while waiting for string", "NOTE: argument must have a \"%d\" in it so the number of seconds\nleft until getkey times out can be printed" },*/
-            { "message", 'm', POPT_ARG_STRING, &waitmessage, 0, "Message to print out while waiting for string\nNOTE: message must have a \"%d\" in it, to hold the number of seconds left to wait", NULL },
+            { "message", 'm', POPT_ARG_STRING, &waitmessage, 0, "Message to print out while waiting for string\nNOTE: The message may have a \"%d\" in it, to hold the number of seconds left to wait.", NULL },
             { "ignore-control-chars", 'i', POPT_ARG_NONE, &ignore_control, 0, "Ignore Control-C and Control-D", NULL },
             POPT_AUTOHELP
             POPT_TABLEEND
         };
 
-	strcpy(list, "");
-        context = poptGetContext("getkey", argc, argv, options, 
+	context = poptGetContext("getkey", argc, (const char **)argv, options,
                                 POPT_CONTEXT_POSIXMEHARDER);
         poptSetOtherOptionHelp(context, "[keys]");
 
@@ -66,44 +64,51 @@
 
             return -1;
         }
-        fooptr = poptGetArg(context);
-	if (fooptr != NULL) {
-	    strncpy(list, fooptr, sizeof(list) - 1);
-	    list[99] = '\0';
-	    for (x=0;list[x];x++) list[x]=toupper(list[x]);
-	}
+        list = poptGetArg(context);
+	if (list != NULL) {
+	    char *p;
+
+	    p = strdup(list);
+	    list = p;
+	    while (*p != 0) {
+		*p = toupper(*p);
+		p++;
+	    }
+	} else
+	    list = default_list;
 	if (waitseconds) {
+	    if (waitseconds < 0) {
+		fprintf(stderr, "--wait: Invalid time %d seconds\n",
+			waitseconds);
+		return -1;
+	    }
 	    alarmlen = waitseconds;
 	}
-	foo[0]=foo[1]='\0';
 
+	tcgetattr(0,&tp);
+	orig_tp = tp;
 	signal(SIGTERM,reset_term);
-	alarm(alarmlen);
-	signal(SIGALRM,reset_term);
+	if (alarmlen != 0) {
+	    signal(SIGALRM,reset_term);
+	    alarm(alarmlen);
+	}
 
-	tcgetattr(0,&tp);
-	tp_if=tp.c_iflag;
-	tp_of=tp.c_oflag;
-	tp_lf=tp.c_lflag;
 	tp.c_iflag=0;
 	tp.c_oflag &= ~OPOST;
 	tp.c_lflag &= ~(ISIG | ICANON);
 	tcsetattr(0,TCSANOW,&tp);
-	tp.c_iflag=tp_if;
-	tp.c_oflag=tp_of;
-	tp.c_lflag=tp_lf;
 
 	ufds.events = POLLIN;
 	ufds.fd = 0;
 
-	if (waitseconds && waitmessage) {
+	if (waitmessage) {
 	    waitprint = alloca (strlen(waitmessage)+15); /* long enough */
 	    waitprint[0] = '\r';
 	    waitsprint = waitprint + 1;
 	}
 
 	while (1) {
-	    if (waitseconds && waitmessage) {
+	    if (waitmessage) {
 		sprintf (waitsprint, waitmessage, waitseconds);
 		write (1, waitprint, strlen(waitprint));
 	    }
@@ -113,19 +118,18 @@
 		waitseconds--;
 	    }
 	    if (r > 0) {
-		read(0,foo,1);
-		foo[0]=toupper(foo[0]);
+		char ch;
+
+		read(0, &ch, sizeof(ch));
+		ch = toupper(ch);
 		/* Die if we get a control-c or control-d */
-                if (ignore_control == 0) {
-		    if (foo[0]==3 || foo[0]==4) reset_term(1);
-                }
+                if (ignore_control == 0 && (ch == 3 || ch == 4))
+		    reset_term(1);
 		/* Don't let a null character be interpreted as a match
-		   by strstr */
-		if (foo[0] != 0) {
-		    if (strcmp(list, "") == 0 || strstr(list,foo)) {
-		      reset_term(0);
-		    }
-		}
+		   by strchr */
+		if (ch != 0
+		    && (strcmp(list, "") == 0 || strchr(list, ch) != NULL))
+		    reset_term(0);
 	    }
 	}
 }


More information about the pld-cvs-commit mailing list