命令功能:默认输出tty名称
使用了-s选项会检查STDIN_FILENO是否存在,存在就返回EXIT_SUCCESS不输出任何消息,只打印状态掩码的退出。不存在就返回TTY_STDIN_NOTTY退出
tty -s 可以于检查标准输入是否存在
核心函数: isatty函数检查给定的设备类型(在这里用于检查标准输入是否存在)
char * ttyname(int desc); 由文件描述符查出对应的文件名(在这里传入STDIN_FILENO用来获取当前进程的tty)
#include <config.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include "system.h"
#include "error.h"
#include "quote.h"
/* Exit statuses. */
/* 退出状态 */
enum
{
TTY_STDIN_NOTTY = 1,
TTY_FAILURE = 2,
TTY_WRITE_ERROR = 3
};
/* 程序名 */
#define PROGRAM_NAME "tty"
#define AUTHORS proper_name ("David MacKenzie")
/* 如果为true,则返回退出状态,但不产生输出(处理选项:-s 记录是否开启了-s选项) */
static bool silent;
/* 选项结构体 */
static struct option const longopts[] =
{
{"silent", no_argument, NULL, 's'},
{"quiet", no_argument, NULL, 's'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
/* 提示函数 */
void
usage (int status)
{
if (status != EXIT_SUCCESS)
emit_try_help ();
else
{
printf (_("Usage: %s [OPTION]...\n"), program_name);
fputs (_("\
Print the file name of the terminal connected to standard input.\n\
\n\
-s, --silent, --quiet print nothing, only return an exit status\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
int
main (int argc, char **argv)
{
int optc;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
initialize_exit_failure (TTY_WRITE_ERROR);
atexit (close_stdout);
/* 默认不开启-s */
silent = false;
while ((optc = getopt_long (argc, argv, "s", longopts, NULL)) != -1)
{
switch (optc)
{
case 's':
silent = true; /* 开启-s,什么都不打印,只返回状态码 */
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (TTY_FAILURE);
}
}
/* 有选项以外的参数就报错 */
if (optind < argc)
{
error (0, 0, _("extra operand %s"), quote (argv[optind]));
usage (TTY_FAILURE);
}
errno = ENOENT;
/* 处理选项:-s 开启了-s,直接返回EXIT_SUCCESS退出 */
if (silent)
return isatty (STDIN_FILENO) ? EXIT_SUCCESS : TTY_STDIN_NOTTY; /* 这里不直接return是因为要用isatty检查STDIN_FILENO标准输入是否存在。标准输入存在的话就正常退出,否则TTY_STDIN_NOTTY没有标准输入的退出码 */
int status = EXIT_SUCCESS; /* 退出状态设为正常退出 */
char const *tty = ttyname (STDIN_FILENO); /* 获取标准输入的tty。获取失败的话tty会指向NULL并设置errno,成功的话就指向终端名 */
/* ttyname获取失败的处理 */
if (! tty)
{
tty = _("not a tty");
status = TTY_STDIN_NOTTY;
}
/* 输出tty和状态掩码并退出 */
puts (tty);
return status;
}