|
|
f7e20b2 |
From bc6e654149018090b7954e6667d3c7e7654625f6 Mon Sep 17 00:00:00 2001
|
|
|
f7e20b2 |
From: =?UTF-8?q?Dan=20Hor=C3=A1k?= <dan@danny.cz>
|
|
|
f7e20b2 |
Date: Fri, 28 Jan 2011 14:18:39 +0100
|
|
|
f7e20b2 |
Subject: [PATCH 53/61] ttyrun: run a program if a terminal device is available
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
Summary: ttyrun: run a program if a terminal device is available
|
|
|
f7e20b2 |
Description: Depending on your setup, Linux on System z might or might not
|
|
|
f7e20b2 |
provide a particular terminal or console. ttyrun safely starts
|
|
|
f7e20b2 |
getty programs and prevents respawns through the init program
|
|
|
f7e20b2 |
if a terminal is not available.
|
|
|
f7e20b2 |
---
|
|
|
f7e20b2 |
iucvterm/doc/Makefile | 2 +-
|
|
|
f7e20b2 |
iucvterm/doc/ttyrun.8 | 146 +++++++++++++++++++++++++++++++++++++++
|
|
|
f7e20b2 |
iucvterm/src/Makefile | 11 +++-
|
|
|
f7e20b2 |
iucvterm/src/ttyrun.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
f7e20b2 |
4 files changed, 339 insertions(+), 3 deletions(-)
|
|
|
f7e20b2 |
create mode 100644 iucvterm/doc/ttyrun.8
|
|
|
f7e20b2 |
create mode 100644 iucvterm/src/ttyrun.c
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
diff --git a/iucvterm/doc/Makefile b/iucvterm/doc/Makefile
|
|
|
f7e20b2 |
index 5815f21..a646765 100644
|
|
|
f7e20b2 |
--- a/iucvterm/doc/Makefile
|
|
|
f7e20b2 |
+++ b/iucvterm/doc/Makefile
|
|
|
f7e20b2 |
@@ -2,7 +2,7 @@
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
include ../../common.mak
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
-MANS = iucvconn.1 iucvtty.1 ts-shell.1 hvc_iucv.9 chiucvallow.8
|
|
|
f7e20b2 |
+MANS = iucvconn.1 iucvtty.1 ts-shell.1 hvc_iucv.9 chiucvallow.8 ttyrun.8
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
all:
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
diff --git a/iucvterm/doc/ttyrun.8 b/iucvterm/doc/ttyrun.8
|
|
|
f7e20b2 |
new file mode 100644
|
|
|
f7e20b2 |
index 0000000..fc7a16f
|
|
|
f7e20b2 |
--- /dev/null
|
|
|
f7e20b2 |
+++ b/iucvterm/doc/ttyrun.8
|
|
|
f7e20b2 |
@@ -0,0 +1,146 @@
|
|
|
f7e20b2 |
+.\" ttyrun.8
|
|
|
f7e20b2 |
+.\"
|
|
|
f7e20b2 |
+.\"
|
|
|
f7e20b2 |
+.\" Copyright IBM Corp. 2010
|
|
|
f7e20b2 |
+.\" Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
|
|
f7e20b2 |
+.\" -------------------------------------------------------------------------
|
|
|
f7e20b2 |
+.TH "ttyrun" "8" "April 2010" "s390-tools" "System Management Commands"
|
|
|
f7e20b2 |
+.LO 8
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.ds s ttyrun
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SH NAME
|
|
|
f7e20b2 |
+ttyrun \- Start a program if a specified terminal device is available
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SH SYNOPSIS
|
|
|
f7e20b2 |
+.B \*s
|
|
|
f7e20b2 |
+.RB [ \-e | \-\-exitstatus
|
|
|
f7e20b2 |
+.IR status ]
|
|
|
f7e20b2 |
+.I term
|
|
|
f7e20b2 |
+.I program
|
|
|
f7e20b2 |
+.RI [ "program_options" ]
|
|
|
f7e20b2 |
+.br
|
|
|
f7e20b2 |
+.B \*s
|
|
|
f7e20b2 |
+.RB [ \-h | \-\-help ]
|
|
|
f7e20b2 |
+.br
|
|
|
f7e20b2 |
+.B \*s
|
|
|
f7e20b2 |
+.RB [ \-v | \-\-version ]
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SH DESCRIPTION
|
|
|
f7e20b2 |
+\fB\*s\fP is typically started during system initialization and is used
|
|
|
f7e20b2 |
+to prevent a respawn through the
|
|
|
f7e20b2 |
+.BR init (8)
|
|
|
f7e20b2 |
+program when a terminal is not available.
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+\fIterm\fP is the name of the terminal device and is a path relative to
|
|
|
f7e20b2 |
+the \f(CW/dev\fP directory, for example, specify \f(CWhvc0\fP for
|
|
|
f7e20b2 |
+\f(CW/dev/hvc0\fP.
|
|
|
f7e20b2 |
+.br
|
|
|
f7e20b2 |
+If the specified terminal device can be opened, \fB\*s\fP starts the
|
|
|
f7e20b2 |
+specified program.
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+If the terminal device cannot be opened, the behavior of \fB\*s\fP
|
|
|
f7e20b2 |
+depends on the \fB\-e\fP option:
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.RS 2
|
|
|
f7e20b2 |
+.IP "\(bu" 2
|
|
|
f7e20b2 |
+If the \fB\-e\fP option has been specified, \fB\*s\fP exits with the
|
|
|
f7e20b2 |
+specified return value, or
|
|
|
f7e20b2 |
+.IP "\(bu" 2
|
|
|
f7e20b2 |
+If the \fB\-e\fP option has not been specified, \fB\*s\fP sleeps until
|
|
|
f7e20b2 |
+it receives a signal that causes an exit.
|
|
|
f7e20b2 |
+.RE
|
|
|
f7e20b2 |
+.PP
|
|
|
f7e20b2 |
+\fIprogram\fP is an absolute path to the program to be started by
|
|
|
f7e20b2 |
+\fB\*s\fP and \fIprogram_options\fP specify additional arguments.
|
|
|
f7e20b2 |
+Depending on the program, arguments might be required. The variable
|
|
|
f7e20b2 |
+\f(CW%t\fP in the \fIprogram_options\fP is resolved to the terminal
|
|
|
f7e20b2 |
+device specified with \fIterm\fP.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SH OPTIONS
|
|
|
f7e20b2 |
+.TP
|
|
|
f7e20b2 |
+.BR \-e ", " \-\-exitstatus\~\fIstatus\fP
|
|
|
f7e20b2 |
+Specifies an exit status that is returned when the terminal device
|
|
|
f7e20b2 |
+is not available. \fIstatus\fP must be an integer in the range 1 to 255.
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+You can use this status value in an upstart job file to prevent
|
|
|
f7e20b2 |
+respawning.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.TP
|
|
|
f7e20b2 |
+.BR \-h ", " \-\-help
|
|
|
f7e20b2 |
+Displays a short help text, then exits.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.TP
|
|
|
f7e20b2 |
+.BR \-v ", " \-\-version
|
|
|
f7e20b2 |
+Displays the version number of \fB\*s\fP, then exits.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SH "RETURN VALUES"
|
|
|
f7e20b2 |
+\fB\*s\fP exits with one of the following return values to report an
|
|
|
f7e20b2 |
+error condition:
|
|
|
f7e20b2 |
+.TP
|
|
|
f7e20b2 |
+.B 1
|
|
|
f7e20b2 |
+\fB\*s\fP has been started with an argument that is not valid or
|
|
|
f7e20b2 |
+required but missing.
|
|
|
f7e20b2 |
+.TP
|
|
|
f7e20b2 |
+.B 2
|
|
|
f7e20b2 |
+\fB\*s\fP could open the file specified for \fIterm\fP but the
|
|
|
f7e20b2 |
+file is not a terminal device.
|
|
|
f7e20b2 |
+.TP
|
|
|
f7e20b2 |
+.B 3
|
|
|
f7e20b2 |
+\fB\*s\fP could not start the specified program.
|
|
|
f7e20b2 |
+.PP
|
|
|
f7e20b2 |
+The return values 1 to 3 might also be returned when the \fB\-e\fP
|
|
|
f7e20b2 |
+option is used and the terminal device is not available.
|
|
|
f7e20b2 |
+.TP
|
|
|
f7e20b2 |
+.B 4 \- 255
|
|
|
f7e20b2 |
+The terminal device is not available and the \fB\-e\fP option
|
|
|
f7e20b2 |
+specifies an exit status in this range.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SH "EXAMPLES"
|
|
|
f7e20b2 |
+.SS inittab
|
|
|
f7e20b2 |
+To start \fB/sbin/agetty\fP on terminal device "hvc1", specify:
|
|
|
f7e20b2 |
+.PP
|
|
|
f7e20b2 |
+.ft CW
|
|
|
f7e20b2 |
+.in +0.25in
|
|
|
f7e20b2 |
+.nf
|
|
|
f7e20b2 |
+h1:2345:respawn:/sbin/\*s hvc1 /sbin/agetty -L 9600 %t linux
|
|
|
f7e20b2 |
+.fi
|
|
|
f7e20b2 |
+.in -0.25in
|
|
|
f7e20b2 |
+.ft
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SS upstart job/event files
|
|
|
f7e20b2 |
+To start \fB/sbin/agetty\fP on terminal device "hvc1", add the following
|
|
|
f7e20b2 |
+settings to the job file:
|
|
|
f7e20b2 |
+.PP
|
|
|
f7e20b2 |
+.ft CW
|
|
|
f7e20b2 |
+.in +0.25in
|
|
|
f7e20b2 |
+.nf
|
|
|
f7e20b2 |
+respawn
|
|
|
f7e20b2 |
+normal exit 42
|
|
|
f7e20b2 |
+exec /sbin/\*s -e 42 hvc1 /sbin/agetty -L 9600 %t linux
|
|
|
f7e20b2 |
+.fi
|
|
|
f7e20b2 |
+.in -0.25in
|
|
|
f7e20b2 |
+.ft
|
|
|
f7e20b2 |
+.PP
|
|
|
f7e20b2 |
+With the normal exit statement, you specify an exit status that will
|
|
|
f7e20b2 |
+prevent upstart from respawning the program. To prevent respawning with
|
|
|
f7e20b2 |
+\fB\*s\fP, you must specify the same value for the \fB\-e\fP option.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.
|
|
|
f7e20b2 |
+.SH "SEE ALSO"
|
|
|
f7e20b2 |
+.BR agetty (8),
|
|
|
f7e20b2 |
+.BR mingetty (8),
|
|
|
f7e20b2 |
+.BR inittab (5),
|
|
|
f7e20b2 |
+.BR events (5)
|
|
|
f7e20b2 |
diff --git a/iucvterm/src/Makefile b/iucvterm/src/Makefile
|
|
|
f7e20b2 |
index f1f8f7c..369c887 100644
|
|
|
f7e20b2 |
--- a/iucvterm/src/Makefile
|
|
|
f7e20b2 |
+++ b/iucvterm/src/Makefile
|
|
|
f7e20b2 |
@@ -11,20 +11,27 @@ CPPFLAGS += -DUSE_NLS -DGETTEXT_TEXTDOMAIN=\"$(GETTEXT_TEXTDOMAIN)\"
|
|
|
f7e20b2 |
#CPPFLAGS += -D__DEBUG__
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
PROGRAMS = iucvconn iucvtty
|
|
|
f7e20b2 |
+SYSTOOLS = ttyrun
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
-all: $(PROGRAMS)
|
|
|
f7e20b2 |
+all: $(PROGRAMS) $(SYSTOOLS)
|
|
|
f7e20b2 |
check:
|
|
|
f7e20b2 |
install:
|
|
|
f7e20b2 |
for prg in $(PROGRAMS); do \
|
|
|
f7e20b2 |
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$prg $(USRBINDIR) ; \
|
|
|
f7e20b2 |
done
|
|
|
f7e20b2 |
+ for prg in $(SYSTOOLS); do \
|
|
|
f7e20b2 |
+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $$prg $(BINDIR) ; \
|
|
|
f7e20b2 |
+ done
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
clean:
|
|
|
f7e20b2 |
- -rm -f *.o $(PROGRAMS)
|
|
|
f7e20b2 |
+ -rm -f *.o $(PROGRAMS) $(SYSTOOLS)
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
iucvconn: iucvconn.o getopt.o auditlog.o functions.o
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
iucvtty: LDLIBS = -lutil
|
|
|
f7e20b2 |
iucvtty: iucvtty.o getopt.o auditlog.o functions.o
|
|
|
f7e20b2 |
|
|
|
f7e20b2 |
+ttyrun: GETTEXT_TEXTDOMAIN = ttyrun
|
|
|
f7e20b2 |
+ttyrun: ttyrun.o
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
.PHONY: install clean
|
|
|
f7e20b2 |
diff --git a/iucvterm/src/ttyrun.c b/iucvterm/src/ttyrun.c
|
|
|
f7e20b2 |
new file mode 100644
|
|
|
f7e20b2 |
index 0000000..55c2bc2
|
|
|
f7e20b2 |
--- /dev/null
|
|
|
f7e20b2 |
+++ b/iucvterm/src/ttyrun.c
|
|
|
f7e20b2 |
@@ -0,0 +1,183 @@
|
|
|
f7e20b2 |
+/*
|
|
|
f7e20b2 |
+ * ttyrun - Start a program if a specified terminal device is available
|
|
|
f7e20b2 |
+ *
|
|
|
f7e20b2 |
+ *
|
|
|
f7e20b2 |
+ * ttyrun is typically used to prevent a respawn through the init(8)
|
|
|
f7e20b2 |
+ * program when a terminal is not available.
|
|
|
f7e20b2 |
+ * ttyrun runs the specific program if the specified terminal device
|
|
|
f7e20b2 |
+ * can be opened successfully. Otherwise the program enters a sleep or
|
|
|
f7e20b2 |
+ * exits with a specified return value.
|
|
|
f7e20b2 |
+ *
|
|
|
f7e20b2 |
+ * Example: To start /sbin/agetty on terminal device hvc1, use:
|
|
|
f7e20b2 |
+ *
|
|
|
f7e20b2 |
+ * h1:2345:respawn:/sbin/ttyrun hvc1 /sbin/agetty -L 9600 %t linux
|
|
|
f7e20b2 |
+ *
|
|
|
f7e20b2 |
+ * Note: %t is resolved to the terminal device "hvc1" before /sbin/agetty
|
|
|
f7e20b2 |
+ * is started.
|
|
|
f7e20b2 |
+ *
|
|
|
f7e20b2 |
+ * Return values:
|
|
|
f7e20b2 |
+ * 1 - invalid argument or parameter is missing
|
|
|
f7e20b2 |
+ * 2 - terminal does not resolve to a terminal device
|
|
|
f7e20b2 |
+ * 3 - starting the specified program failed
|
|
|
f7e20b2 |
+ * 1..255 - terminal is not available and the return code is
|
|
|
f7e20b2 |
+ * specified with the -e option
|
|
|
f7e20b2 |
+ *
|
|
|
f7e20b2 |
+ * Copyright IBM Corp. 2010
|
|
|
f7e20b2 |
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
|
|
f7e20b2 |
+ */
|
|
|
f7e20b2 |
+#include <errno.h>
|
|
|
f7e20b2 |
+#include <getopt.h>
|
|
|
f7e20b2 |
+#include <limits.h>
|
|
|
f7e20b2 |
+#include <signal.h>
|
|
|
f7e20b2 |
+#include <stdlib.h>
|
|
|
f7e20b2 |
+#include <stdio.h>
|
|
|
f7e20b2 |
+#include <string.h>
|
|
|
f7e20b2 |
+#include <sys/types.h>
|
|
|
f7e20b2 |
+#include <syslog.h>
|
|
|
f7e20b2 |
+#include <fcntl.h>
|
|
|
f7e20b2 |
+#include <unistd.h>
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+#include "zt_common.h"
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+#define TTY_ESCAPE_STR "%t"
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+#define EXIT_INVALID_ARG 1
|
|
|
f7e20b2 |
+#define EXIT_NO_TERMINAL 2
|
|
|
f7e20b2 |
+#define EXIT_EXEC_FAILED 3
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+static const char usage[] =
|
|
|
f7e20b2 |
+"Usage: %s [-e status] <term> <program> [<program_options>]\n"
|
|
|
f7e20b2 |
+" %s [-h|--help] [-v|--version]\n"
|
|
|
f7e20b2 |
+"\n"
|
|
|
f7e20b2 |
+"Start the program if the specified terminal device is available.\n"
|
|
|
f7e20b2 |
+"If the terminal device cannot be opened, sleep until a signal is received\n"
|
|
|
f7e20b2 |
+"that causes an exit or exit with the return value specified with status.\n"
|
|
|
f7e20b2 |
+"\n"
|
|
|
f7e20b2 |
+"-e, --exitstatus Specifies an exit status in the range 1 to 255.\n"
|
|
|
f7e20b2 |
+"-h, --help Displays this help, then exits.\n"
|
|
|
f7e20b2 |
+"-v, --version Displays version information, then exits.\n";
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+static void help_exit(const char *prg)
|
|
|
f7e20b2 |
+{
|
|
|
f7e20b2 |
+ printf(usage, prg, prg);
|
|
|
f7e20b2 |
+ exit(EXIT_SUCCESS);
|
|
|
f7e20b2 |
+}
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+static void version_exit(const char *prg)
|
|
|
f7e20b2 |
+{
|
|
|
f7e20b2 |
+ printf("%s: Start a program if a terminal device is available, "
|
|
|
f7e20b2 |
+ "version %s\n", prg, RELEASE_STRING);
|
|
|
f7e20b2 |
+ printf("Copyright IBM Corp. 2010\n");
|
|
|
f7e20b2 |
+ exit(EXIT_SUCCESS);
|
|
|
f7e20b2 |
+}
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+static void err_exit(const char *prg, const char *msg)
|
|
|
f7e20b2 |
+{
|
|
|
f7e20b2 |
+ fprintf(stderr, "%s: %s\n", prg, msg);
|
|
|
f7e20b2 |
+ exit(EXIT_INVALID_ARG);
|
|
|
f7e20b2 |
+}
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+static void wait_and_exit(void)
|
|
|
f7e20b2 |
+{
|
|
|
f7e20b2 |
+ /* sleep until a signal is received, then exit */
|
|
|
f7e20b2 |
+ pause();
|
|
|
f7e20b2 |
+ exit(EXIT_SUCCESS);
|
|
|
f7e20b2 |
+}
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+static const struct option prog_opts[] = {
|
|
|
f7e20b2 |
+ { "help", no_argument, NULL, 'h'},
|
|
|
f7e20b2 |
+ { "version", no_argument, NULL, 'v'},
|
|
|
f7e20b2 |
+ { "exitstatus", required_argument, NULL, 'e'},
|
|
|
f7e20b2 |
+ { NULL, no_argument, NULL, 0 },
|
|
|
f7e20b2 |
+};
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+int main(int argc, char *argv[])
|
|
|
f7e20b2 |
+{
|
|
|
f7e20b2 |
+ int rc, tty, i, c, index, done, term_index;
|
|
|
f7e20b2 |
+ char terminal[PATH_MAX] = "";
|
|
|
f7e20b2 |
+ unsigned long exitstatus;
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ /* parse command options */
|
|
|
f7e20b2 |
+ if (argc == 1)
|
|
|
f7e20b2 |
+ err_exit(argv[0], "One or more options are required but missing");
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ exitstatus = done = term_index = 0;
|
|
|
f7e20b2 |
+ while (!done) {
|
|
|
f7e20b2 |
+ c = getopt_long(argc, argv, "-hve:", prog_opts, NULL);
|
|
|
f7e20b2 |
+ switch (c) {
|
|
|
f7e20b2 |
+ case -1:
|
|
|
f7e20b2 |
+ done = 1;
|
|
|
f7e20b2 |
+ break;
|
|
|
f7e20b2 |
+ case 1:
|
|
|
f7e20b2 |
+ /* the first non-optional argument must be the
|
|
|
f7e20b2 |
+ * terminal device */
|
|
|
f7e20b2 |
+ if (!strncmp(optarg, "/", 1))
|
|
|
f7e20b2 |
+ strncpy(terminal, optarg, PATH_MAX - 1);
|
|
|
f7e20b2 |
+ else
|
|
|
f7e20b2 |
+ snprintf(terminal, PATH_MAX, "/dev/%s", optarg);
|
|
|
f7e20b2 |
+ terminal[PATH_MAX - 1] = 0;
|
|
|
f7e20b2 |
+ term_index = optind - 1;
|
|
|
f7e20b2 |
+ done = 1;
|
|
|
f7e20b2 |
+ break;
|
|
|
f7e20b2 |
+ case 'e':
|
|
|
f7e20b2 |
+ errno = 0;
|
|
|
f7e20b2 |
+ exitstatus = strtoul(optarg, (char **) NULL, 10);
|
|
|
f7e20b2 |
+ if (errno == ERANGE)
|
|
|
f7e20b2 |
+ err_exit(argv[0], "The exit status must be "
|
|
|
f7e20b2 |
+ "an integer in the range 1 to 255");
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ if (!exitstatus || exitstatus > 255)
|
|
|
f7e20b2 |
+ err_exit(argv[0], "The exit status must be "
|
|
|
f7e20b2 |
+ "in the range 1 to 255");
|
|
|
f7e20b2 |
+ break;
|
|
|
f7e20b2 |
+ case 'h':
|
|
|
f7e20b2 |
+ help_exit(argv[0]);
|
|
|
f7e20b2 |
+ case 'v':
|
|
|
f7e20b2 |
+ version_exit(argv[0]);
|
|
|
f7e20b2 |
+ case '?':
|
|
|
f7e20b2 |
+ fprintf(stderr, "Try %s --help for more information\n",
|
|
|
f7e20b2 |
+ argv[0]);
|
|
|
f7e20b2 |
+ exit(EXIT_INVALID_ARG);
|
|
|
f7e20b2 |
+ }
|
|
|
f7e20b2 |
+ }
|
|
|
f7e20b2 |
+ index = optind;
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ /* check terminal */
|
|
|
f7e20b2 |
+ if (!strlen(terminal))
|
|
|
f7e20b2 |
+ err_exit(argv[0], "You must specify the name of "
|
|
|
f7e20b2 |
+ "a terminal device");
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ /* any program to start? */
|
|
|
f7e20b2 |
+ if (index == argc)
|
|
|
f7e20b2 |
+ err_exit(argv[0], "You must specify a program to start");
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ /* open and check terminal device */
|
|
|
f7e20b2 |
+ tty = open(terminal, O_NOCTTY | O_RDONLY | O_NONBLOCK);
|
|
|
f7e20b2 |
+ if (tty == -1) {
|
|
|
f7e20b2 |
+ openlog(argv[0], LOG_PID, LOG_DAEMON);
|
|
|
f7e20b2 |
+ syslog(LOG_INFO, "Could not open tty %s (%s)", terminal,
|
|
|
f7e20b2 |
+ strerror(errno));
|
|
|
f7e20b2 |
+ closelog();
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ /* enter wait or exit */
|
|
|
f7e20b2 |
+ if (exitstatus)
|
|
|
f7e20b2 |
+ exit(exitstatus);
|
|
|
f7e20b2 |
+ wait_and_exit();
|
|
|
f7e20b2 |
+ }
|
|
|
f7e20b2 |
+ rc = !isatty(tty);
|
|
|
f7e20b2 |
+ close(tty);
|
|
|
f7e20b2 |
+ if (rc)
|
|
|
f7e20b2 |
+ exit(EXIT_NO_TERMINAL);
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ /* start getty program */
|
|
|
f7e20b2 |
+ for (i = index; i < argc; i++)
|
|
|
f7e20b2 |
+ if (!strcmp(argv[i], TTY_ESCAPE_STR) && term_index)
|
|
|
f7e20b2 |
+ argv[i] = argv[term_index];
|
|
|
f7e20b2 |
+ if (execv(argv[index], argv + index))
|
|
|
f7e20b2 |
+ exit(EXIT_EXEC_FAILED);
|
|
|
f7e20b2 |
+
|
|
|
f7e20b2 |
+ exit(EXIT_SUCCESS);
|
|
|
f7e20b2 |
+}
|
|
|
f7e20b2 |
--
|
|
|
f7e20b2 |
1.7.3.5
|
|
|
f7e20b2 |
|