diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-09 21:44:51 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-09 21:44:51 +0100 |
| commit | bcdb9b8762d14634afb570fe48db9fa62d8c0109 (patch) | |
| tree | bd891883a264771d1039b6eb251b41e685520c6b | |
| parent | e9d12b57bfb941e754d09a7d5f54c183ca7dbb25 (diff) | |
| download | busybox-w32-bcdb9b8762d14634afb570fe48db9fa62d8c0109.tar.gz busybox-w32-bcdb9b8762d14634afb570fe48db9fa62d8c0109.tar.bz2 busybox-w32-bcdb9b8762d14634afb570fe48db9fa62d8c0109.zip | |
getty: fix -i (was ignored)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | include/usage.src.h | 17 | ||||
| -rw-r--r-- | loginutils/getty.c | 135 |
2 files changed, 67 insertions, 85 deletions
diff --git a/include/usage.src.h b/include/usage.src.h index ea0e6a452..ef2bebd8b 100644 --- a/include/usage.src.h +++ b/include/usage.src.h | |||
| @@ -1394,23 +1394,6 @@ INSERT | |||
| 1394 | #define getsebool_full_usage "\n\n" \ | 1394 | #define getsebool_full_usage "\n\n" \ |
| 1395 | " -a Show all selinux booleans" | 1395 | " -a Show all selinux booleans" |
| 1396 | 1396 | ||
| 1397 | #define getty_trivial_usage \ | ||
| 1398 | "[OPTIONS] BAUD_RATE TTY [TERMTYPE]" | ||
| 1399 | #define getty_full_usage "\n\n" \ | ||
| 1400 | "Open a tty, prompt for a login name, then invoke /bin/login\n" \ | ||
| 1401 | "\nOptions:" \ | ||
| 1402 | "\n -h Enable hardware (RTS/CTS) flow control" \ | ||
| 1403 | "\n -i Don't display /etc/issue before running login" \ | ||
| 1404 | "\n -L Local line, don't do carrier detect" \ | ||
| 1405 | "\n -m Get baud rate from modem's CONNECT status message" \ | ||
| 1406 | "\n -w Wait for a CR or LF before sending /etc/issue" \ | ||
| 1407 | "\n -n Don't prompt the user for a login name" \ | ||
| 1408 | "\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue" \ | ||
| 1409 | "\n -l LOGIN Invoke LOGIN instead of /bin/login" \ | ||
| 1410 | "\n -t SEC Terminate after SEC if no username is read" \ | ||
| 1411 | "\n -I INITSTR Send INITSTR before anything else" \ | ||
| 1412 | "\n -H HOST Log HOST into the utmp file as the hostname" \ | ||
| 1413 | |||
| 1414 | #define gunzip_trivial_usage \ | 1397 | #define gunzip_trivial_usage \ |
| 1415 | "[-cft] [FILE]..." | 1398 | "[-cft] [FILE]..." |
| 1416 | #define gunzip_full_usage "\n\n" \ | 1399 | #define gunzip_full_usage "\n\n" \ |
diff --git a/loginutils/getty.c b/loginutils/getty.c index 76b0de449..0f5e333a7 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
| @@ -31,14 +31,25 @@ | |||
| 31 | * System V, assume it is SunOS 4. | 31 | * System V, assume it is SunOS 4. |
| 32 | */ | 32 | */ |
| 33 | #ifdef LOGIN_PROCESS /* defined in System V utmp.h */ | 33 | #ifdef LOGIN_PROCESS /* defined in System V utmp.h */ |
| 34 | #include <sys/utsname.h> | 34 | # include <sys/utsname.h> |
| 35 | #else /* if !sysV style, wtmp/utmp code is off */ | 35 | #else /* if !sysV style, wtmp/utmp code is off */ |
| 36 | #undef ENABLE_FEATURE_UTMP | 36 | # undef ENABLE_FEATURE_UTMP |
| 37 | #undef ENABLE_FEATURE_WTMP | 37 | # undef ENABLE_FEATURE_WTMP |
| 38 | #define ENABLE_FEATURE_UTMP 0 | 38 | # define ENABLE_FEATURE_UTMP 0 |
| 39 | #define ENABLE_FEATURE_WTMP 0 | 39 | # define ENABLE_FEATURE_WTMP 0 |
| 40 | #endif /* LOGIN_PROCESS */ | 40 | #endif /* LOGIN_PROCESS */ |
| 41 | 41 | ||
| 42 | |||
| 43 | /* The following is used for understandable diagnostics. */ | ||
| 44 | #ifdef DEBUGGING | ||
| 45 | static FILE *dbf; | ||
| 46 | # define DEBUGTERM "/dev/ttyp0" | ||
| 47 | # define debug(...) do { fprintf(dbf, __VA_ARGS__); fflush(dbf); } while (0) | ||
| 48 | #else | ||
| 49 | # define debug(...) ((void)0) | ||
| 50 | #endif | ||
| 51 | |||
| 52 | |||
| 42 | /* | 53 | /* |
| 43 | * Things you may want to modify. | 54 | * Things you may want to modify. |
| 44 | * | 55 | * |
| @@ -51,13 +62,15 @@ | |||
| 51 | #undef HANDLE_ALLCAPS | 62 | #undef HANDLE_ALLCAPS |
| 52 | #undef ANCIENT_BS_KILL_CHARS | 63 | #undef ANCIENT_BS_KILL_CHARS |
| 53 | 64 | ||
| 65 | #undef _PATH_LOGIN | ||
| 54 | #define _PATH_LOGIN "/bin/login" | 66 | #define _PATH_LOGIN "/bin/login" |
| 55 | 67 | ||
| 56 | /* If ISSUE is not defined, getty will never display the contents of the | 68 | /* Displayed before the login prompt. |
| 69 | * If ISSUE is not defined, getty will never display the contents of the | ||
| 57 | * /etc/issue file. You will not want to spit out large "issue" files at the | 70 | * /etc/issue file. You will not want to spit out large "issue" files at the |
| 58 | * wrong baud rate. | 71 | * wrong baud rate. |
| 59 | */ | 72 | */ |
| 60 | #define ISSUE "/etc/issue" /* displayed before the login prompt */ | 73 | #define ISSUE "/etc/issue" |
| 61 | 74 | ||
| 62 | /* Some shorthands for control characters. */ | 75 | /* Some shorthands for control characters. */ |
| 63 | #define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */ | 76 | #define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */ |
| @@ -83,7 +96,6 @@ | |||
| 83 | 96 | ||
| 84 | /* Storage for command-line options. */ | 97 | /* Storage for command-line options. */ |
| 85 | struct options { | 98 | struct options { |
| 86 | int flags; /* toggle switches, see below */ | ||
| 87 | unsigned timeout; /* time-out period */ | 99 | unsigned timeout; /* time-out period */ |
| 88 | const char *login; /* login program */ | 100 | const char *login; /* login program */ |
| 89 | const char *tty; /* name of tty */ | 101 | const char *tty; /* name of tty */ |
| @@ -111,7 +123,6 @@ struct chardata { | |||
| 111 | #endif | 123 | #endif |
| 112 | }; | 124 | }; |
| 113 | 125 | ||
| 114 | |||
| 115 | /* Initial values for the above. */ | 126 | /* Initial values for the above. */ |
| 116 | static const struct chardata init_chardata = { | 127 | static const struct chardata init_chardata = { |
| 117 | DEF_ERASE, /* default erase character */ | 128 | DEF_ERASE, /* default erase character */ |
| @@ -123,30 +134,37 @@ static const struct chardata init_chardata = { | |||
| 123 | #endif | 134 | #endif |
| 124 | }; | 135 | }; |
| 125 | 136 | ||
| 126 | static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:wn"; | ||
| 127 | #define F_INITSTRING (1 << 0) /* -I initstring is set */ | ||
| 128 | #define F_LOCAL (1 << 1) /* -L force local */ | ||
| 129 | #define F_FAKEHOST (1 << 2) /* -H fake hostname */ | ||
| 130 | #define F_CUSTISSUE (1 << 3) /* -f give alternative issue file */ | ||
| 131 | #define F_RTSCTS (1 << 4) /* -h enable RTS/CTS flow control */ | ||
| 132 | #define F_ISSUE (1 << 5) /* -i display /etc/issue */ | ||
| 133 | #define F_LOGIN (1 << 6) /* -l non-default login program */ | ||
| 134 | #define F_PARSE (1 << 7) /* -m process modem status messages */ | ||
| 135 | #define F_TIMEOUT (1 << 8) /* -t time out */ | ||
| 136 | #define F_WAITCRLF (1 << 9) /* -w wait for CR or LF */ | ||
| 137 | #define F_NOPROMPT (1 << 10) /* -n don't ask for login name */ | ||
| 138 | |||
| 139 | |||
| 140 | #define line_buf bb_common_bufsiz1 | 137 | #define line_buf bb_common_bufsiz1 |
| 141 | 138 | ||
| 142 | /* The following is used for understandable diagnostics. */ | 139 | //usage:#define getty_trivial_usage |
| 143 | #ifdef DEBUGGING | 140 | //usage: "[OPTIONS] BAUD_RATE TTY [TERMTYPE]" |
| 144 | static FILE *dbf; | 141 | //usage:#define getty_full_usage "\n\n" |
| 145 | #define DEBUGTERM "/dev/ttyp0" | 142 | //usage: "Open a tty, prompt for a login name, then invoke /bin/login\n" |
| 146 | #define debug(...) do { fprintf(dbf, __VA_ARGS__); fflush(dbf); } while (0) | 143 | //usage: "\nOptions:" |
| 147 | #else | 144 | //usage: "\n -h Enable hardware (RTS/CTS) flow control" |
| 148 | #define debug(...) ((void)0) | 145 | //usage: "\n -i Don't display /etc/issue" |
| 149 | #endif | 146 | //usage: "\n -L Local line, don't do carrier detect" |
| 147 | //usage: "\n -m Get baud rate from modem's CONNECT status message" | ||
| 148 | //usage: "\n -w Wait for a CR or LF before sending /etc/issue" | ||
| 149 | //usage: "\n -n Don't prompt the user for a login name" | ||
| 150 | //usage: "\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue" | ||
| 151 | //usage: "\n -l LOGIN Invoke LOGIN instead of /bin/login" | ||
| 152 | //usage: "\n -t SEC Terminate after SEC if no username is read" | ||
| 153 | //usage: "\n -I INITSTR Send INITSTR before anything else" | ||
| 154 | //usage: "\n -H HOST Log HOST into the utmp file as the hostname" | ||
| 155 | |||
| 156 | static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:wn"; | ||
| 157 | #define F_INITSTRING (1 << 0) /* -I */ | ||
| 158 | #define F_LOCAL (1 << 1) /* -L */ | ||
| 159 | #define F_FAKEHOST (1 << 2) /* -H */ | ||
| 160 | #define F_CUSTISSUE (1 << 3) /* -f */ | ||
| 161 | #define F_RTSCTS (1 << 4) /* -h */ | ||
| 162 | #define F_NOISSUE (1 << 5) /* -i */ | ||
| 163 | #define F_LOGIN (1 << 6) /* -l */ | ||
| 164 | #define F_PARSE (1 << 7) /* -m */ | ||
| 165 | #define F_TIMEOUT (1 << 8) /* -t */ | ||
| 166 | #define F_WAITCRLF (1 << 9) /* -w */ | ||
| 167 | #define F_NOPROMPT (1 << 10) /* -n */ | ||
| 150 | 168 | ||
| 151 | 169 | ||
| 152 | /* bcode - convert speed string to speed code; return <= 0 on failure */ | 170 | /* bcode - convert speed string to speed code; return <= 0 on failure */ |
| @@ -181,18 +199,18 @@ static void parse_speeds(struct options *op, char *arg) | |||
| 181 | static void parse_args(char **argv, struct options *op, char **fakehost_p) | 199 | static void parse_args(char **argv, struct options *op, char **fakehost_p) |
| 182 | { | 200 | { |
| 183 | char *ts; | 201 | char *ts; |
| 202 | int flags; | ||
| 184 | 203 | ||
| 185 | opt_complementary = "-2:t+"; /* at least 2 args; -t N */ | 204 | opt_complementary = "-2:t+"; /* at least 2 args; -t N */ |
| 186 | op->flags = getopt32(argv, opt_string, | 205 | flags = getopt32(argv, opt_string, |
| 187 | &(op->initstring), fakehost_p, &(op->issue), | 206 | &(op->initstring), fakehost_p, &(op->issue), |
| 188 | &(op->login), &op->timeout); | 207 | &(op->login), &op->timeout); |
| 189 | argv += optind; | 208 | if (flags & F_INITSTRING) { |
| 190 | if (op->flags & F_INITSTRING) { | ||
| 191 | op->initstring = xstrdup(op->initstring); | 209 | op->initstring = xstrdup(op->initstring); |
| 192 | /* decode \ddd octal codes into chars */ | 210 | /* decode \ddd octal codes into chars */ |
| 193 | strcpy_and_process_escape_sequences((char*)op->initstring, op->initstring); | 211 | strcpy_and_process_escape_sequences((char*)op->initstring, op->initstring); |
| 194 | } | 212 | } |
| 195 | op->flags ^= F_ISSUE; /* invert flag "show /etc/issue" */ | 213 | argv += optind; |
| 196 | debug("after getopt\n"); | 214 | debug("after getopt\n"); |
| 197 | 215 | ||
| 198 | /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ | 216 | /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ |
| @@ -217,17 +235,6 @@ static void open_tty(const char *tty) | |||
| 217 | { | 235 | { |
| 218 | /* Set up new standard input, unless we are given an already opened port. */ | 236 | /* Set up new standard input, unless we are given an already opened port. */ |
| 219 | if (NOT_LONE_DASH(tty)) { | 237 | if (NOT_LONE_DASH(tty)) { |
| 220 | // struct stat st; | ||
| 221 | // int cur_dir_fd; | ||
| 222 | // int fd; | ||
| 223 | |||
| 224 | /* Sanity checks... */ | ||
| 225 | // cur_dir_fd = xopen(".", O_DIRECTORY | O_NONBLOCK); | ||
| 226 | // xchdir("/dev"); | ||
| 227 | // xstat(tty, &st); | ||
| 228 | // if (!S_ISCHR(st.st_mode)) | ||
| 229 | // bb_error_msg_and_die("not a character device"); | ||
| 230 | |||
| 231 | if (tty[0] != '/') | 238 | if (tty[0] != '/') |
| 232 | tty = xasprintf("/dev/%s", tty); /* will leak it */ | 239 | tty = xasprintf("/dev/%s", tty); /* will leak it */ |
| 233 | 240 | ||
| @@ -236,15 +243,6 @@ static void open_tty(const char *tty) | |||
| 236 | close(0); | 243 | close(0); |
| 237 | /*fd =*/ xopen(tty, O_RDWR | O_NONBLOCK); /* uses fd 0 */ | 244 | /*fd =*/ xopen(tty, O_RDWR | O_NONBLOCK); /* uses fd 0 */ |
| 238 | 245 | ||
| 239 | // /* Restore current directory */ | ||
| 240 | // fchdir(cur_dir_fd); | ||
| 241 | |||
| 242 | /* Open the tty as standard input, continued */ | ||
| 243 | // xmove_fd(fd, 0); | ||
| 244 | // /* fd is >= cur_dir_fd, and cur_dir_fd gets closed too here: */ | ||
| 245 | // while (fd > 2) | ||
| 246 | // close(fd--); | ||
| 247 | |||
| 248 | /* Set proper protections and ownership. */ | 246 | /* Set proper protections and ownership. */ |
| 249 | fchown(0, 0, 0); /* 0:0 */ | 247 | fchown(0, 0, 0); /* 0:0 */ |
| 250 | fchmod(0, 0620); /* crw--w---- */ | 248 | fchmod(0, 0620); /* crw--w---- */ |
| @@ -259,7 +257,7 @@ static void open_tty(const char *tty) | |||
| 259 | } | 257 | } |
| 260 | 258 | ||
| 261 | /* termios_init - initialize termios settings */ | 259 | /* termios_init - initialize termios settings */ |
| 262 | static void termios_init(struct termios *tp, int speed, struct options *op) | 260 | static void termios_init(struct termios *tp, int speed) |
| 263 | { | 261 | { |
| 264 | speed_t ispeed, ospeed; | 262 | speed_t ispeed, ospeed; |
| 265 | /* | 263 | /* |
| @@ -278,7 +276,7 @@ static void termios_init(struct termios *tp, int speed, struct options *op) | |||
| 278 | ospeed = cfgetospeed(tp); | 276 | ospeed = cfgetospeed(tp); |
| 279 | } | 277 | } |
| 280 | tp->c_cflag = CS8 | HUPCL | CREAD; | 278 | tp->c_cflag = CS8 | HUPCL | CREAD; |
| 281 | if (op->flags & F_LOCAL) | 279 | if (option_mask32 & F_LOCAL) |
| 282 | tp->c_cflag |= CLOCAL; | 280 | tp->c_cflag |= CLOCAL; |
| 283 | cfsetispeed(tp, ispeed); | 281 | cfsetispeed(tp, ispeed); |
| 284 | cfsetospeed(tp, ospeed); | 282 | cfsetospeed(tp, ospeed); |
| @@ -293,7 +291,7 @@ static void termios_init(struct termios *tp, int speed, struct options *op) | |||
| 293 | 291 | ||
| 294 | /* Optionally enable hardware flow control */ | 292 | /* Optionally enable hardware flow control */ |
| 295 | #ifdef CRTSCTS | 293 | #ifdef CRTSCTS |
| 296 | if (op->flags & F_RTSCTS) | 294 | if (option_mask32 & F_RTSCTS) |
| 297 | tp->c_cflag |= CRTSCTS; | 295 | tp->c_cflag |= CRTSCTS; |
| 298 | #endif | 296 | #endif |
| 299 | 297 | ||
| @@ -364,7 +362,8 @@ static void auto_baud(char *buf, unsigned size_buf, struct termios *tp) | |||
| 364 | static void do_prompt(struct options *op) | 362 | static void do_prompt(struct options *op) |
| 365 | { | 363 | { |
| 366 | #ifdef ISSUE | 364 | #ifdef ISSUE |
| 367 | print_login_issue(op->issue, op->tty); | 365 | if (!(option_mask32 & F_NOISSUE)) |
| 366 | print_login_issue(op->issue, op->tty); | ||
| 368 | #endif | 367 | #endif |
| 369 | print_login_prompt(); | 368 | print_login_prompt(); |
| 370 | } | 369 | } |
| @@ -429,7 +428,7 @@ static char *get_logname(char *logname, unsigned size_logname, | |||
| 429 | return NULL; | 428 | return NULL; |
| 430 | 429 | ||
| 431 | /* Do parity bit handling. */ | 430 | /* Do parity bit handling. */ |
| 432 | if (!(op->flags & F_LOCAL) && (c & 0x80)) { /* "parity" bit on? */ | 431 | if (!(option_mask32 & F_LOCAL) && (c & 0x80)) { /* "parity" bit on? */ |
| 433 | bits = 1; | 432 | bits = 1; |
| 434 | mask = 1; | 433 | mask = 1; |
| 435 | while (mask & 0x7f) { | 434 | while (mask & 0x7f) { |
| @@ -499,7 +498,7 @@ static char *get_logname(char *logname, unsigned size_logname, | |||
| 499 | } | 498 | } |
| 500 | 499 | ||
| 501 | /* termios_final - set the final tty mode bits */ | 500 | /* termios_final - set the final tty mode bits */ |
| 502 | static void termios_final(struct options *op, struct termios *tp, struct chardata *cp) | 501 | static void termios_final(struct termios *tp, struct chardata *cp) |
| 503 | { | 502 | { |
| 504 | /* General terminal-independent stuff. */ | 503 | /* General terminal-independent stuff. */ |
| 505 | tp->c_iflag |= IXON | IXOFF; /* 2-way flow control */ | 504 | tp->c_iflag |= IXON | IXOFF; /* 2-way flow control */ |
| @@ -554,7 +553,7 @@ static void termios_final(struct options *op, struct termios *tp, struct chardat | |||
| 554 | #endif | 553 | #endif |
| 555 | /* Optionally enable hardware flow control */ | 554 | /* Optionally enable hardware flow control */ |
| 556 | #ifdef CRTSCTS | 555 | #ifdef CRTSCTS |
| 557 | if (op->flags & F_RTSCTS) | 556 | if (option_mask32 & F_RTSCTS) |
| 558 | tp->c_cflag |= CRTSCTS; | 557 | tp->c_cflag |= CRTSCTS; |
| 559 | #endif | 558 | #endif |
| 560 | 559 | ||
| @@ -655,24 +654,24 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
| 655 | 654 | ||
| 656 | /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */ | 655 | /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */ |
| 657 | debug("calling termios_init\n"); | 656 | debug("calling termios_init\n"); |
| 658 | termios_init(&termios, options.speeds[0], &options); | 657 | termios_init(&termios, options.speeds[0]); |
| 659 | 658 | ||
| 660 | /* Write the modem init string and DON'T flush the buffers */ | 659 | /* Write the modem init string and DON'T flush the buffers */ |
| 661 | if (options.flags & F_INITSTRING) { | 660 | if (option_mask32 & F_INITSTRING) { |
| 662 | debug("writing init string\n"); | 661 | debug("writing init string\n"); |
| 663 | full_write1_str(options.initstring); | 662 | full_write1_str(options.initstring); |
| 664 | } | 663 | } |
| 665 | 664 | ||
| 666 | /* Optionally detect the baud rate from the modem status message */ | 665 | /* Optionally detect the baud rate from the modem status message */ |
| 667 | debug("before autobaud\n"); | 666 | debug("before autobaud\n"); |
| 668 | if (options.flags & F_PARSE) | 667 | if (option_mask32 & F_PARSE) |
| 669 | auto_baud(line_buf, sizeof(line_buf), &termios); | 668 | auto_baud(line_buf, sizeof(line_buf), &termios); |
| 670 | 669 | ||
| 671 | /* Set the optional timer */ | 670 | /* Set the optional timer */ |
| 672 | alarm(options.timeout); /* if 0, alarm is not set */ | 671 | alarm(options.timeout); /* if 0, alarm is not set */ |
| 673 | 672 | ||
| 674 | /* Optionally wait for CR or LF before writing /etc/issue */ | 673 | /* Optionally wait for CR or LF before writing /etc/issue */ |
| 675 | if (options.flags & F_WAITCRLF) { | 674 | if (option_mask32 & F_WAITCRLF) { |
| 676 | char ch; | 675 | char ch; |
| 677 | 676 | ||
| 678 | debug("waiting for cr-lf\n"); | 677 | debug("waiting for cr-lf\n"); |
| @@ -685,7 +684,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
| 685 | } | 684 | } |
| 686 | 685 | ||
| 687 | logname = NULL; | 686 | logname = NULL; |
| 688 | if (!(options.flags & F_NOPROMPT)) { | 687 | if (!(option_mask32 & F_NOPROMPT)) { |
| 689 | /* NB:termios_init already set line speed | 688 | /* NB:termios_init already set line speed |
| 690 | * to options.speeds[0] */ | 689 | * to options.speeds[0] */ |
| 691 | int baud_index = 0; | 690 | int baud_index = 0; |
| @@ -709,7 +708,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
| 709 | alarm(0); | 708 | alarm(0); |
| 710 | 709 | ||
| 711 | /* Finalize the termios settings. */ | 710 | /* Finalize the termios settings. */ |
| 712 | termios_final(&options, &termios, &chardata); | 711 | termios_final(&termios, &chardata); |
| 713 | 712 | ||
| 714 | /* Now the newline character should be properly written. */ | 713 | /* Now the newline character should be properly written. */ |
| 715 | full_write(STDOUT_FILENO, "\n", 1); | 714 | full_write(STDOUT_FILENO, "\n", 1); |
