3

I want to remove the default newline inserted before the content of /etc/issue on login prompt in tty. I'm using agetty and systemd.

I tried to add the --nonewline option to my getty@tty5.service :

ExecStart=/sbin/agetty --nonewline --noclear %I $TERM

That result in :

# systemctl status -l getty@tty5.service
● getty@tty5.service - Getty on tty5
  Loaded: loaded (/usr/lib/systemd/system/getty@.service; disabled)
  Active: failed (Result: start-limit) since sam. 2014-05-17 23:50:13 CEST; 56s ago
    Docs: man:agetty(8)
          man:systemd-getty-generator(8)
          http://0pointer.de/blog/projects/serial-console.html
 Process: 14538 ExecStart=/sbin/agetty --nonewline --noclear %I $TERM (code=exited, status=1/FAILURE)
Main PID: 14538 (code=exited, status=1/FAILURE)

systemd[1]: getty@tty5.service has no holdoff time, scheduling restart.
systemd[1]: Stopping Getty on tty5...
systemd[1]: Starting Getty on tty5...
systemd[1]: getty@tty5.service start request repeated too quickly, refusing to start.
systemd[1]: Failed to start Getty on tty5.
systemd[1]: Unit getty@tty5.service entered failed state.

And I get :

# journalctl --no-pager -b -u getty@tty5.service
-- Logs begin at sam. 2013-10-12 00:20:12 CEST, end at sam. 2014-05-17 23:52:49 CEST. --
systemd[1]: Starting Getty on tty5...
systemd[1]: Started Getty on tty5.
agetty[14497]: Usage:
agetty[14497]: agetty [options] <line> [<baud_rate>,...] [<termtype>]
agetty[14497]: agetty [options] <baud_rate>,... <line> [<termtype>]
agetty[14497]: Options:
agetty[14497]: -8, --8bits                assume 8-bit tty
agetty[14497]: -a, --autologin <user>     login the specified user automatically
agetty[14497]: -c, --noreset              do not reset control mode
agetty[14497]: -E, --remote               use -r <hostname> for login(1)
agetty[14497]: -f, --issue-file <file>    display issue file
agetty[14497]: -h, --flow-control         enable hardware flow control
agetty[14497]: -H, --host <hostname>      specify login host
agetty[14497]: -i, --noissue              do not display issue file
agetty[14497]: -I, --init-string <string> set init string
agetty[14497]: -l, --login-program <file> specify login program
agetty[14497]: -L, --local-line[=<mode>]  control the local line flag
agetty[14497]: -m, --extract-baud         extract baud rate during connect
agetty[14497]: -n, --skip-login           do not prompt for login
agetty[14497]: -o, --login-options <opts> options that are passed to login
agetty[14497]: -p, --login-pause          wait for any key before the login
agetty[14497]: -r, --chroot <dir>         change root to the directory
agetty[14497]: -R, --hangup               do virtually hangup on the tty
agetty[14497]: -s, --keep-baud            try to keep baud rate after break
agetty[14497]: -t, --timeout <number>     login process timeout
agetty[14497]: -U, --detect-case          detect uppercase terminal
agetty[14497]: -w, --wait-cr              wait carriage-return
agetty[14497]: --noclear              do not clear the screen before prompt
agetty[14497]: --nohints              do not print hints
agetty[14497]: --nonewline            do not print a newline before issue
agetty[14497]: --nohostname           no hostname at all will be shown
agetty[14497]: --long-hostname        show full qualified hostname
agetty[14497]: --erase-chars <string> additional backspace chars
agetty[14497]: --kill-chars <string>  additional kill chars
agetty[14497]: --help                 display this help and exit
agetty[14497]: --version              output version information and exit
agetty[14497]: For more details see agetty(8).
systemd[1]: getty@tty5.service has no holdoff time, scheduling restart.
systemd[1]: Stopping Getty on tty5...

Why agetty don't want to recognize the option ? Is there another way to do that ?

1
3

You have hit a bug! There's a F_NONL directive that never gets called in the agetty binary as can be seen in the sources:

...
#define F_NONL      (1<<17) /* No newline before issue */
...
/* Parse command-line arguments. */
static void parse_args(int argc, char **argv, struct options *op)
{
    int c;

    enum {
            VERSION_OPTION = CHAR_MAX + 1,
            NOHINTS_OPTION,
            NOHOSTNAME_OPTION,
            LONGHOSTNAME_OPTION,
            HELP_OPTION,
            ERASE_CHARS_OPTION,
            KILL_CHARS_OPTION,
    };
    const struct option longopts[] = {
            {  "8bits",      no_argument,    0,  '8'  },
            {  "autologin",      required_argument,  0,  'a'  },
            ...
            {  "skip-login",     no_argument,    0,  'n'  },
            {  "nonewline",      no_argument,    0,  'N'  },
    while ((c = getopt_long(argc, argv,
               "8a:cC:d:Ef:hH:iI:Jl:L::mnNo:pP:r:Rst:Uw", longopts,
                NULL)) != -1) {
        switch (c) {
        case '8':
            op->flags |= F_EIGHTBITS;
            break;
        case 'a':
            op->autolog = optarg;
            break;
        case 'c':
            op->flags |= F_KEEPCFLAGS;
            break;
        case 'C':
            op->chdir = optarg;
            break;
        case 'd':
            op->delay = atoi(optarg);
            break;
        case 'E':
            op->flags |= F_REMOTE;
            break;
        case 'f':
            op->flags |= F_CUSTISSUE;
            op->issue = optarg;
            break;
        case 'h':
            op->flags |= F_RTSCTS;
            break;
        case 'H':
            fakehost = optarg;
            break;
        case 'i':
            op->flags &= ~F_ISSUE;
            break;
        case 'I':
            init_special_char(optarg, op);
            op->flags |= F_INITSTRING;
            break;
        case 'J':
            op->flags |= F_NOCLEAR;
            break;
        case 'l':
            op->login = optarg;
            break;
        case 'L':
            /* -L and -L=always have the same meaning */
            op->clocal = CLOCAL_MODE_ALWAYS;
            if (optarg) {
                if (strcmp(optarg, "=always") == 0)
                    op->clocal = CLOCAL_MODE_ALWAYS;
                else if (strcmp(optarg, "=never") == 0)
                    op->clocal = CLOCAL_MODE_NEVER;
                else if (strcmp(optarg, "=auto") == 0)
                    op->clocal = CLOCAL_MODE_AUTO;
                else
                    log_err(_("invalid argument of --local-line"));
            }
            break;
        case 'm':
            op->flags |= F_PARSE;
            break;
        case 'n':
            op->flags |= F_NOPROMPT;
            break;
        case 'o':
            op->logopt = optarg;
            break;
        case 'p':
            op->flags |= F_LOGINPAUSE;
            break;
        case 'P':
            op->nice = atoi(optarg);
            break;
        case 'r':
            op->chroot = optarg;
            break;
        case 'R':
            op->flags |= F_HANGUP;
            break;
        case 's':
            op->flags |= F_KEEPSPEED;
            break;
        case 't':
            if ((op->timeout = atoi(optarg)) <= 0)
                log_err(_("bad timeout value: %s"), optarg);
            break;
        case 'U':
            op->flags |= F_LCUC;
            break;
        case 'w':
            op->flags |= F_WAITCRLF;
            break;
        case NOHINTS_OPTION:
            op->flags |= F_NOHINTS;
            break;
        case NOHOSTNAME_OPTION:
            op->flags |= F_NOHOSTNAME;
            break;
        case LONGHOSTNAME_OPTION:
            op->flags |= F_LONGHNAME;
            break;
        case ERASE_CHARS_OPTION:
            op->erasechars = optarg;
            break;
        case KILL_CHARS_OPTION:
            op->killchars = optarg;
            break;
        case VERSION_OPTION:
            printf(_("%s from %s\n"), program_invocation_short_name,
                   PACKAGE_STRING);
            exit(EXIT_SUCCESS);
        case HELP_OPTION:
            usage(stdout);
        default:
            usage(stderr);
        }
    }

In the while loop there should be a block like below, which is missing.

case 'N':
op->flags |= F_NONL;
break;

I think is a trivial patch to add. You can check the full source code in GitHub or kernel.org.

2
  • Thanks ! Plus the option isn't implemented in 2.24 as it's said in the changelog. I submitted a bug report and created a patch.
    – lbeziaud
    May 17 '14 at 23:17
  • @user2535792 I presume this one ;)
    – Braiam
    May 18 '14 at 1:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.