aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2014-01-30 13:00:58 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2014-01-30 13:00:58 +0200
commit9e2d258c81af9f8cedba2e4b8874fbaea59b43c4 (patch)
treed470f085625c6434d4661b185c981f8065c14d3c
parenta3987da2a573bd2438f15df6faa680922025be18 (diff)
downloadcpio-9e2d258c81af9f8cedba2e4b8874fbaea59b43c4.tar.gz
cpio-9e2d258c81af9f8cedba2e4b8874fbaea59b43c4.tar.bz2
Use exit codes consistenly.
-rw-r--r--src/copyin.c10
-rw-r--r--src/copyout.c6
-rw-r--r--src/main.c150
-rw-r--r--src/util.c24
4 files changed, 102 insertions, 88 deletions
diff --git a/src/copyin.c b/src/copyin.c
index 3282816..78ffdd7 100644
--- a/src/copyin.c
+++ b/src/copyin.c
@@ -953,13 +953,13 @@ read_in_header (struct cpio_file_stat *file_hdr, int in_des)
int peeked_bytes;
while (archive_format == arf_unknown)
{
peeked_bytes = tape_buffered_peek (tmpbuf, in_des, 512);
if (peeked_bytes < 6)
- error (1, 0, _("premature end of archive"));
+ error (PAXEXIT_FAILURE, 0, _("premature end of archive"));
if (!strncmp (tmpbuf, "070701", 6))
archive_format = arf_newascii;
else if (!strncmp (tmpbuf, "070707", 6))
archive_format = arf_oldascii;
else if (!strncmp (tmpbuf, "070702", 6))
@@ -1286,27 +1286,27 @@ process_copy_in ()
if (rename_batch_file)
{
rename_in = fopen (rename_batch_file, "r");
if (rename_in == NULL)
{
- error (2, errno, TTY_NAME);
+ error (PAXEXIT_FAILURE, errno, TTY_NAME);
}
}
else if (rename_flag)
{
/* Open interactive file pair for rename operation. */
tty_in = fopen (TTY_NAME, "r");
if (tty_in == NULL)
{
- error (2, errno, TTY_NAME);
+ error (PAXEXIT_FAILURE, errno, TTY_NAME);
}
tty_out = fopen (TTY_NAME, "w");
if (tty_out == NULL)
{
- error (2, errno, TTY_NAME);
+ error (PAXEXIT_FAILURE, errno, TTY_NAME);
}
}
/* Get date and time if needed for processing the table option. */
if (table_flag && verbose_flag)
{
@@ -1320,13 +1320,13 @@ process_copy_in ()
input_is_special = 1;
input_is_seekable = 0;
}
else
{
if (fstat (in_file_des, &file_stat))
- error (1, errno, _("standard input is closed"));
+ error (PAXEXIT_FAILURE, errno, _("standard input is closed"));
input_is_special =
#ifdef S_ISBLK
S_ISBLK (file_stat.st_mode) ||
#endif
S_ISCHR (file_stat.st_mode);
input_is_seekable = S_ISREG (file_stat.st_mode);
diff --git a/src/copyout.c b/src/copyout.c
index a5a8931..63785ff 100644
--- a/src/copyout.c
+++ b/src/copyout.c
@@ -45,22 +45,22 @@ read_for_checksum (int in_file_des, int file_size, char *file_name)
crc = 0;
for (bytes_left = file_size; bytes_left > 0; bytes_left -= bytes_read)
{
bytes_read = read (in_file_des, buf, BUFSIZ);
if (bytes_read < 0)
- error (1, errno, _("cannot read checksum for %s"), file_name);
+ error (PAXEXIT_FAILURE, errno, _("cannot read checksum for %s"), file_name);
if (bytes_read == 0)
break;
if (bytes_left < bytes_read)
bytes_read = bytes_left;
for (i = 0; i < bytes_read; ++i)
crc += buf[i] & 0xff;
}
if (lseek (in_file_des, 0L, SEEK_SET))
- error (1, errno, _("cannot read checksum for %s"), file_name);
+ error (PAXEXIT_FAILURE, errno, _("cannot read checksum for %s"), file_name);
return crc;
}
/* Write out NULs to fill out the rest of the current block on
OUT_FILE_DES. */
@@ -603,13 +603,13 @@ process_copy_out ()
output_is_special = 1;
output_is_seekable = 0;
}
else
{
if (fstat (out_file_des, &file_stat))
- error (1, errno, _("standard output is closed"));
+ error (PAXEXIT_FAILURE, errno, _("standard output is closed"));
output_is_special =
#ifdef S_ISBLK
S_ISBLK (file_stat.st_mode) ||
#endif
S_ISCHR (file_stat.st_mode);
output_is_seekable = S_ISREG (file_stat.st_mode);
diff --git a/src/main.c b/src/main.c
index d352e25..25320b5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -33,12 +33,13 @@
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#include <progname.h>
+#include <closeout.h>
#include "filetypes.h"
#include "cpiohdr.h"
#include "dstring.h"
#include "extern.h"
#include <rmt.h>
@@ -77,17 +78,19 @@ Examples:\n\
cpio -o < name-list [> archive]\n\
# Extract files from the archive\n\
cpio -i [< archive]\n\
# Copy files named in name-list to destination-directory\n\
cpio -p destination-directory < name-list\n");
+static void usage (int status);
+
/* Print usage error message and exit with error. */
#define CHECK_USAGE(cond, opt, mode_opt) \
if (cond) \
- ERROR((PAXEXIT_FAILURE, 0, _("%s is meaningless with %s"), opt, mode_opt));
+ USAGE_ERROR ((0, 0, _("%s is meaningless with %s"), opt, mode_opt));
static struct argp_option options[] = {
/* ********** */
#define GRID 10
{NULL, 0, NULL, 0,
N_("Main operation mode:"), GRID },
@@ -306,30 +309,30 @@ parse_opt (int key, char *arg, struct argp_state *state)
io_block_size = 5120;
break;
case BLOCK_SIZE_OPTION: /* --block-size */
io_block_size = atoi (arg);
if (io_block_size < 1)
- error (2, 0, _("invalid block size"));
+ USAGE_ERROR ((0, 0, _("invalid block size")));
io_block_size *= 512;
break;
case 'c': /* Use the old portable ASCII format. */
if (archive_format != arf_unknown)
- error (0, EXIT_FAILURE, _("Archive format multiply defined"));
+ USAGE_ERROR ((0, 0, _("Archive format multiply defined")));
#ifdef SVR4_COMPAT
archive_format = arf_newascii; /* -H newc. */
#else
archive_format = arf_oldascii; /* -H odc. */
#endif
break;
case 'C': /* Block size. */
io_block_size = atoi (arg);
if (io_block_size < 1)
- error (2, 0, _("invalid block size"));
+ USAGE_ERROR ((0, 0, _("invalid block size")));
break;
case 'd': /* Create directories where needed. */
create_dir_flag = true;
break;
@@ -348,13 +351,13 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'F': /* Archive file name. */
archive_name = arg;
break;
case 'H': /* Header format name. */
if (archive_format != arf_unknown)
- error (PAXEXIT_FAILURE, 0, _("Archive format multiply defined"));
+ USAGE_ERROR ((0, 0, _("Archive format multiply defined")));
if (!strcasecmp (arg, "crc"))
archive_format = arf_crcascii;
else if (!strcasecmp (arg, "newc"))
archive_format = arf_newascii;
else if (!strcasecmp (arg, "odc"))
archive_format = arf_oldascii;
@@ -366,20 +369,20 @@ parse_opt (int key, char *arg, struct argp_state *state)
archive_format = arf_tar;
else if (!strcasecmp (arg, "hpodc"))
archive_format = arf_hpoldascii;
else if (!strcasecmp (arg, "hpbin"))
archive_format = arf_hpbinary;
else
- error (2, 0, _("\
+ USAGE_ERROR ((0, 0, _("\
invalid archive format `%s'; valid formats are:\n\
-crc newc odc bin ustar tar (all-caps also recognized)"), arg);
+crc newc odc bin ustar tar (all-caps also recognized)"), arg));
break;
case 'i': /* Copy-in mode. */
if (copy_function != 0)
- error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
+ USAGE_ERROR ((0, 0, _("Mode already defined")));
copy_function = process_copy_in;
break;
case 'I': /* Input archive file name. */
input_archive_name = arg;
break;
@@ -411,20 +414,20 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */
no_abs_paths_flag = false;
break;
case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
if (set_owner_flag || set_group_flag)
- error (PAXEXIT_FAILURE, 0,
- _("--no-preserve-owner cannot be used with --owner"));
+ USAGE_ERROR ((0, 0,
+ _("--no-preserve-owner cannot be used with --owner")));
no_chown_flag = true;
break;
case 'o': /* Copy-out mode. */
if (copy_function != 0)
- error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
+ USAGE_ERROR ((0, 0, _("Mode already defined")));
copy_function = process_copy_out;
break;
case 'O': /* Output archive file name. */
output_archive_name = arg;
break;
@@ -432,13 +435,13 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
case ONLY_VERIFY_CRC_OPTION:
only_verify_crc_flag = true;
break;
case 'p': /* Copy-pass mode. */
if (copy_function != 0)
- error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
+ USAGE_ERROR ((0, 0, _("Mode already defined")));
copy_function = process_copy_pass;
break;
case RSH_COMMAND_OPTION:
rsh_command_option = arg;
break;
@@ -454,21 +457,21 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
case QUIET_OPTION:
quiet_flag = true;
break;
case 'R': /* Set the owner. */
if (no_chown_flag)
- error (PAXEXIT_FAILURE, 0,
- _("--owner cannot be used with --no-preserve-owner"));
+ USAGE_ERROR ((0, 0,
+ _("--owner cannot be used with --no-preserve-owner")));
else
{
char *e, *u, *g;
e = parse_user_spec (arg, &set_owner, &set_group, &u, &g);
if (e)
- error (PAXEXIT_FAILURE, 0, "%s: %s", arg, e);
+ USAGE_ERROR ((0, 0, "%s: %s", arg, e));
if (u)
{
free (u);
set_owner_flag = true;
}
if (g)
@@ -502,13 +505,13 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
case 'V': /* Print `.' for each file. */
dot_flag = true;
break;
case 'W':
if (warn_control (arg))
- argp_error (state, _("Invalid value for --warning option: %s"), arg);
+ USAGE_ERROR ((0, 0, _("Invalid value for --warning option: %s"), arg));
break;
case SPARSE_OPTION:
sparse_flag = true;
break;
@@ -539,12 +542,20 @@ static struct argp argp = {
doc,
NULL,
NULL,
NULL
};
+static void
+usage (int status)
+{
+ argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
+ close_stdout ();
+ exit (status);
+}
+
/* Process the arguments. Set all options and set up the copy pass
directory or the copy in patterns. */
void
process_args (int argc, char *argv[])
{
@@ -561,109 +572,112 @@ process_args (int argc, char *argv[])
if (copy_function == 0)
{
if (table_flag)
copy_function = process_copy_in;
else
- error (PAXEXIT_FAILURE, 0,
+ USAGE_ERROR ((0, 0,
_("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
- program_name, program_name);
+ program_name, program_name));
}
/* Work around for pcc bug. */
copy_in = process_copy_in;
copy_out = process_copy_out;
if (copy_function == copy_in)
{
archive_des = 0;
- CHECK_USAGE(link_flag, "--link", "--extract");
- CHECK_USAGE(reset_time_flag, "--reset", "--extract");
- CHECK_USAGE(xstat != lstat, "--dereference", "--extract");
- CHECK_USAGE(append_flag, "--append", "--extract");
- CHECK_USAGE(output_archive_name, "-O", "--extract");
+ CHECK_USAGE (link_flag, "--link", "--extract");
+ CHECK_USAGE (reset_time_flag, "--reset", "--extract");
+ CHECK_USAGE (xstat != lstat, "--dereference", "--extract");
+ CHECK_USAGE (append_flag, "--append", "--extract");
+ CHECK_USAGE (output_archive_name, "-O", "--extract");
if (to_stdout_option)
{
- CHECK_USAGE(create_dir_flag, "--make-directories", "--to-stdout");
- CHECK_USAGE(rename_flag, "--rename", "--to-stdout");
- CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--to-stdout");
- CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--to-stdout");
- CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
- "--to-stdout");
+ CHECK_USAGE (create_dir_flag, "--make-directories", "--to-stdout");
+ CHECK_USAGE (rename_flag, "--rename", "--to-stdout");
+ CHECK_USAGE (no_chown_flag, "--no-preserve-owner", "--to-stdout");
+ CHECK_USAGE (set_owner_flag||set_group_flag,
+ "--owner", "--to-stdout");
+ CHECK_USAGE (retain_time_flag, "--preserve-modification-time",
+ "--to-stdout");
}
if (archive_name && input_archive_name)
- error (PAXEXIT_FAILURE, 0,
- _("Both -I and -F are used in copy-in mode"));
+ USAGE_ERROR ((0, 0,
+ _("Both -I and -F are used in copy-in mode")));
if (archive_format == arf_crcascii)
crc_i_flag = true;
num_patterns = argc - index;
save_patterns = &argv[index];
if (input_archive_name)
archive_name = input_archive_name;
}
else if (copy_function == copy_out)
{
if (index != argc)
- error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
+ USAGE_ERROR ((0, 0, _("Too many arguments")));
archive_des = 1;
- CHECK_USAGE(create_dir_flag, "--make-directories", "--create");
- CHECK_USAGE(rename_flag, "--rename", "--create");
- CHECK_USAGE(table_flag, "--list", "--create");
- CHECK_USAGE(unconditional_flag, "--unconditional", "--create");
- CHECK_USAGE(link_flag, "--link", "--create");
- CHECK_USAGE(sparse_flag, "--sparse", "--create");
- CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
- "--create");
- CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--create");
- CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--create");
- CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
- "--create");
- CHECK_USAGE(to_stdout_option, "--to-stdout", "--create");
+ CHECK_USAGE (create_dir_flag, "--make-directories", "--create");
+ CHECK_USAGE (rename_flag, "--rename", "--create");
+ CHECK_USAGE (table_flag, "--list", "--create");
+ CHECK_USAGE (unconditional_flag, "--unconditional", "--create");
+ CHECK_USAGE (link_flag, "--link", "--create");
+ CHECK_USAGE (sparse_flag, "--sparse", "--create");
+ CHECK_USAGE (retain_time_flag, "--preserve-modification-time",
+ "--create");
+ CHECK_USAGE (no_chown_flag, "--no-preserve-owner", "--create");
+ CHECK_USAGE (swap_bytes_flag, "--swap-bytes (--swap)", "--create");
+ CHECK_USAGE (swap_halfwords_flag, "--swap-halfwords (--swap)",
+ "--create");
+ CHECK_USAGE (to_stdout_option, "--to-stdout", "--create");
if (append_flag && !(archive_name || output_archive_name))
- error (PAXEXIT_FAILURE, 0,
- _("--append is used but no archive file name is given (use -F or -O options)"));
+ USAGE_ERROR ((0, 0,
+ _("--append is used but no archive file name "
+ "is given (use -F or -O options)")));
- CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create");
- CHECK_USAGE(input_archive_name, "-I", "--create");
+ CHECK_USAGE (rename_batch_file, "--rename-batch-file", "--create");
+ CHECK_USAGE (input_archive_name, "-I", "--create");
if (archive_name && output_archive_name)
- error (PAXEXIT_FAILURE, 0,
- _("Both -O and -F are used in copy-out mode"));
+ USAGE_ERROR ((0, 0,
+ _("Both -O and -F are used in copy-out mode")));
if (archive_format == arf_unknown)
archive_format = arf_binary;
if (output_archive_name)
archive_name = output_archive_name;
}
else
{
/* Copy pass. */
if (index < argc - 1)
- error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
+ USAGE_ERROR ((0, 0, _("Too many arguments")));
else if (index > argc - 1)
- error (PAXEXIT_FAILURE, 0, _("Not enough arguments"));
+ USAGE_ERROR ((0, 0, _("Not enough arguments")));
if (archive_format != arf_unknown)
- error (PAXEXIT_FAILURE, 0,
- _("Archive format is not specified in copy-pass mode (use --format option)"));
-
- CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through");
- CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
- "--pass-through");
- CHECK_USAGE(table_flag, "--list", "--pass-through");
- CHECK_USAGE(rename_flag, "--rename", "--pass-through");
- CHECK_USAGE(append_flag, "--append", "--pass-through");
- CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through");
- CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames",
- "--pass-through");
- CHECK_USAGE(no_abs_paths_flag, "--absolute-pathnames",
- "--pass-through");
- CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");
+ USAGE_ERROR ((0, 0,
+ _("Archive format is not specified in copy-pass mode "
+ "(use --format option)")));
+
+ CHECK_USAGE (swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through");
+ CHECK_USAGE (swap_halfwords_flag, "--swap-halfwords (--swap)",
+ "--pass-through");
+ CHECK_USAGE (table_flag, "--list", "--pass-through");
+ CHECK_USAGE (rename_flag, "--rename", "--pass-through");
+ CHECK_USAGE (append_flag, "--append", "--pass-through");
+ CHECK_USAGE (rename_batch_file, "--rename-batch-file", "--pass-through");
+ CHECK_USAGE (no_abs_paths_flag, "--no-absolute-pathnames",
+ "--pass-through");
+ CHECK_USAGE (no_abs_paths_flag, "--absolute-pathnames",
+ "--pass-through");
+ CHECK_USAGE (to_stdout_option, "--to-stdout", "--pass-through");
directory_name = argv[index];
}
if (archive_name)
{
diff --git a/src/util.c b/src/util.c
index 2fcab61..f717104 100644
--- a/src/util.c
+++ b/src/util.c
@@ -87,16 +87,16 @@ tape_empty_output_buffer (int out_des)
rest_output_size = output_size - bytes_written;
else
rest_output_size = output_size;
rest_bytes_written = rmtwrite (out_des, output_buffer,
rest_output_size);
if (rest_bytes_written != rest_output_size)
- error (1, errno, _("write error"));
+ error (PAXEXIT_FAILURE, errno, _("write error"));
}
else
- error (1, errno, _("write error"));
+ error (PAXEXIT_FAILURE, errno, _("write error"));
}
output_bytes += output_size;
out_buff = output_buffer;
output_size = 0;
}
@@ -140,15 +140,15 @@ disk_empty_output_buffer (int out_des, bool flush)
else
bytes_written = write (out_des, output_buffer, output_size);
if (bytes_written != output_size)
{
if (bytes_written == -1)
- error (1, errno, _("write error"));
+ error (PAXEXIT_FAILURE, errno, _("write error"));
else
- error (1, 0, _("write error: partial write"));
+ error (PAXEXIT_FAILURE, 0, _("write error: partial write"));
}
output_bytes += output_size;
out_buff = output_buffer;
output_size = 0;
}
@@ -204,13 +204,13 @@ tape_fill_input_buffer (int in_des, int num_bytes)
if (input_size == 0 && input_is_special)
{
get_next_reel (in_des);
input_size = rmtread (in_des, input_buffer, num_bytes);
}
if (input_size < 0)
- error (1, errno, _("read error"));
+ error (PAXEXIT_FAILURE, errno, _("read error"));
if (input_size == 0)
{
error (0, 0, _("premature end of file"));
exit (PAXEXIT_FAILURE);
}
input_bytes += input_size;
@@ -373,13 +373,13 @@ tape_buffered_peek (char *peek_buf, int in_des, int num_bytes)
tmp_input_size = rmtread (in_des, append_buf, io_block_size);
}
else
break;
}
if (tmp_input_size < 0)
- error (1, errno, _("read error"));
+ error (PAXEXIT_FAILURE, errno, _("read error"));
input_bytes += tmp_input_size;
input_size += tmp_input_size;
}
if (num_bytes <= input_size)
got_bytes = num_bytes;
else
@@ -617,13 +617,13 @@ create_all_directories (char *name)
mode = 04700;
}
#endif
if (dir == NULL)
- error (2, 0, _("virtual memory exhausted"));
+ error (PAXEXIT_FAILURE, 0, _("virtual memory exhausted"));
if (dir[0] != '.' || dir[1] != '\0')
{
const char *fmt;
if (warn_option & CPIO_WARN_INTERDIR)
fmt = _("Creating intermediate directory `%s'");
@@ -660,19 +660,19 @@ prepare_append (int out_file_des)
start_of_header = last_header_start;
/* Figure out how many bytes we will rewrite, and where they start. */
useful_bytes_in_block = start_of_header % io_block_size;
start_of_block = start_of_header - useful_bytes_in_block;
if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
- error (1, errno, _("cannot seek on output"));
+ error (PAXEXIT_FAILURE, errno, _("cannot seek on output"));
if (useful_bytes_in_block > 0)
{
tmp_buf = (char *) xmalloc (useful_bytes_in_block);
read (out_file_des, tmp_buf, useful_bytes_in_block);
if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
- error (1, errno, _("cannot seek on output"));
+ error (PAXEXIT_FAILURE, errno, _("cannot seek on output"));
/* fix juo -- is this copy_tape_buf_out? or copy_disk? */
tape_buffered_write (tmp_buf, out_file_des, useful_bytes_in_block);
free (tmp_buf);
}
/* We are done reading the archive, so clear these since they
@@ -820,16 +820,16 @@ get_next_reel (int tape_des)
ds_init (&new_name, 128);
/* Open files for interactive communication. */
tty_in = fopen (TTY_NAME, "r");
if (tty_in == NULL)
- error (2, errno, TTY_NAME);
+ error (PAXEXIT_FAILURE, errno, TTY_NAME);
tty_out = fopen (TTY_NAME, "w");
if (tty_out == NULL)
- error (2, errno, TTY_NAME);
+ error (PAXEXIT_FAILURE, errno, TTY_NAME);
old_tape_des = tape_des;
tape_offline (tape_des);
rmtclose (tape_des);
/* Give message and wait for carrage return. User should hit carrage return
@@ -888,13 +888,13 @@ get_next_reel (int tape_des)
rmtread and rmtwrite) since open will always return the lowest
available file descriptor and we haven't closed any files (e.g.,
stdin, stdout or stderr) that were opened before we originally opened
the archive. */
if (tape_des != old_tape_des)
- error (1, 0, _("internal error: tape descriptor changed from %d to %d"),
+ error (PAXEXIT_FAILURE, 0, _("internal error: tape descriptor changed from %d to %d"),
old_tape_des, tape_des);
free (new_name.ds_string);
fclose (tty_in);
fclose (tty_out);
}

Return to:

Send suggestions and report system problems to the System administrator.