init and ls -l fixes
No binary (build failed)
—
(log yok)
| @@ -1,3 +1,11 @@ | |
| + | 0.34 |
| + | * ls -l now displays lnik names outside the current directory, |
| + | Patch thanks to Eric Delaunay |
| + | * init now properly handles sparc serial consoles and does a |
| + | better job of finding the real consol device rather than using |
| + | /dev/console which doesn't support job control. Patch also |
| + | thanks to Eric Delaunay. |
| + | |
| 0.33 | |
| * Fixed a bug where init could hang instead of rebooting. | |
| * Removed some debugging noise from init.c | |
| @@ -206,7 +206,7 @@ static char append_char(mode_t mode) | |
| ** | |
| **/ | |
| - | static void list_single(const char *name, struct stat *info) |
| + | static void list_single(const char *name, struct stat *info, const char *fullname) |
| { | |
| char scratch[PATH_MAX]; | |
| short len = strlen(name); | |
| @@ -297,12 +297,12 @@ static void list_single(const char *name, struct stat *info) | |
| wr(name, len); | |
| if (S_ISLNK(mode)) { | |
| wr(" -> ", 4); | |
| - | len = readlink(name, scratch, sizeof scratch); |
| + | len = readlink(fullname, scratch, sizeof scratch); |
| if (len > 0) fwrite(scratch, 1, len, stdout); | |
| #ifdef FEATURE_FILETYPECHAR | |
| /* show type of destination */ | |
| if (opts & DISP_FTYPE) { | |
| - | if (!stat(name, info)) { |
| + | if (!stat(fullname, info)) { |
| append = append_char(info->st_mode); | |
| if (append) | |
| fputc(append, stdout); | |
| @@ -372,7 +372,7 @@ static int list_item(const char *name) | |
| if (!S_ISDIR(info.st_mode) || | |
| (opts & DIR_NOLIST)) { | |
| - | list_single(name, &info); |
| + | list_single(name, &info, name); |
| return 0; | |
| } | |
| @@ -424,7 +424,7 @@ static int list_item(const char *name) | |
| strcpy(fnend, entry->d_name); | |
| if (lstat(fullname, &info)) | |
| goto direrr; /* (shouldn't fail) */ | |
| - | list_single(entry->d_name, &info); |
| + | list_single(entry->d_name, &info, fullname); |
| } | |
| closedir(dir); | |
| return 0; | |
| @@ -88,8 +88,14 @@ void message(int device, char *fmt, ...) | |
| /* Take full control of the log tty, and never close it. | |
| * It's mine, all mine! Muhahahaha! */ | |
| - | if (log_fd==-1) { |
| - | if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { |
| + | if (log_fd < 0) { |
| + | if (log == NULL) { |
| + | /* don't even try to log, because there is no such console */ |
| + | log_fd = -2; |
| + | /* log to main console instead */ |
| + | device = CONSOLE; |
| + | } |
| + | else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { |
| log_fd=-1; | |
| fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); | |
| fflush(stderr); | |
| @@ -97,7 +103,7 @@ void message(int device, char *fmt, ...) | |
| } | |
| } | |
| - | if ( (device & LOG) && (log_fd != -1) ) { |
| + | if ( (device & LOG) && (log_fd >= 0) ) { |
| va_start(arguments, fmt); | |
| vdprintf(log_fd, fmt, arguments); | |
| va_end(arguments); | |
| @@ -180,25 +186,40 @@ static void console_init() | |
| int fd; | |
| int tried_devcons = 0; | |
| int tried_vtprimary = 0; | |
| + | struct serial_struct sr; |
| char *s; | |
| if ((s = getenv("CONSOLE")) != NULL) { | |
| console = s; | |
| - | /* Apparently the sparc does wierd things... */ |
| + | } |
| #if defined (__sparc__) | |
| - | if (strncmp( s, "/dev/tty", 8 )==0) { |
| - | switch( s[8]) { |
| - | case 'a': |
| - | s=SERIAL_CON0; |
| - | break; |
| - | case 'b': |
| - | s=SERIAL_CON1; |
| - | } |
| - | } |
| + | /* sparc kernel supports console=tty[ab] parameter which is also |
| + | * passed to init, so catch it here */ |
| + | else if ((s = getenv("console")) != NULL) { |
| + | /* remap tty[ab] to /dev/ttyS[01] */ |
| + | if (strcmp( s, "ttya" )==0) |
| + | console = SERIAL_CON0; |
| + | else if (strcmp( s, "ttyb" )==0) |
| + | console = SERIAL_CON1; |
| + | } |
| #endif | |
| - | } else { |
| - | console = VT_CONSOLE; |
| - | tried_devcons++; |
| + | else { |
| + | struct vt_stat vt; |
| + | static char the_console[13]; |
| + | |
| + | console = the_console; |
| + | /* 2.2 kernels: identify the real console backend and try to use it */ |
| + | if (ioctl(0,TIOCGSERIAL,&sr) == 0) { |
| + | /* this is a serial console */ |
| + | snprintf( the_console, sizeof the_console, "/dev/ttyS%d", sr.line ); |
| + | } |
| + | else if (ioctl(0, VT_GETSTATE, &vt) == 0) { |
| + | /* this is linux virtual tty */ |
| + | snprintf( the_console, sizeof the_console, "/dev/tty%d", vt.v_active ); |
| + | } else { |
| + | console = VT_CONSOLE; |
| + | tried_devcons++; |
| + | } |
| } | |
| while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) { | |
| @@ -219,8 +240,15 @@ static void console_init() | |
| if (fd < 0) | |
| /* Perhaps we should panic here? */ | |
| console = "/dev/null"; | |
| - | else |
| + | else { |
| + | /* check for serial console and disable logging to tty3 & running a |
| + | * shell to tty2 */ |
| + | if (ioctl(0,TIOCGSERIAL,&sr) == 0) { |
| + | log = NULL; |
| + | second_console = NULL; |
| + | } |
| close(fd); | |
| + | } |
| message(LOG, "console=%s\n", console ); | |
| } | |
| @@ -472,7 +500,7 @@ extern int init_main(int argc, char **argv) | |
| if (pid1 == 0 && tty0_commands) { | |
| pid1 = run(tty0_commands, console, wait_for_enter); | |
| } | |
| - | if (pid2 == 0 && tty1_commands) { |
| + | if (pid2 == 0 && tty1_commands && second_console) { |
| pid2 = run(tty1_commands, second_console, TRUE); | |
| } | |
| wpid = wait(&status); | |
| @@ -88,8 +88,14 @@ void message(int device, char *fmt, ...) | |
| /* Take full control of the log tty, and never close it. | |
| * It's mine, all mine! Muhahahaha! */ | |
| - | if (log_fd==-1) { |
| - | if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { |
| + | if (log_fd < 0) { |
| + | if (log == NULL) { |
| + | /* don't even try to log, because there is no such console */ |
| + | log_fd = -2; |
| + | /* log to main console instead */ |
| + | device = CONSOLE; |
| + | } |
| + | else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { |
| log_fd=-1; | |
| fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); | |
| fflush(stderr); | |
| @@ -97,7 +103,7 @@ void message(int device, char *fmt, ...) | |
| } | |
| } | |
| - | if ( (device & LOG) && (log_fd != -1) ) { |
| + | if ( (device & LOG) && (log_fd >= 0) ) { |
| va_start(arguments, fmt); | |
| vdprintf(log_fd, fmt, arguments); | |
| va_end(arguments); | |
| @@ -180,25 +186,40 @@ static void console_init() | |
| int fd; | |
| int tried_devcons = 0; | |
| int tried_vtprimary = 0; | |
| + | struct serial_struct sr; |
| char *s; | |
| if ((s = getenv("CONSOLE")) != NULL) { | |
| console = s; | |
| - | /* Apparently the sparc does wierd things... */ |
| + | } |
| #if defined (__sparc__) | |
| - | if (strncmp( s, "/dev/tty", 8 )==0) { |
| - | switch( s[8]) { |
| - | case 'a': |
| - | s=SERIAL_CON0; |
| - | break; |
| - | case 'b': |
| - | s=SERIAL_CON1; |
| - | } |
| - | } |
| + | /* sparc kernel supports console=tty[ab] parameter which is also |
| + | * passed to init, so catch it here */ |
| + | else if ((s = getenv("console")) != NULL) { |
| + | /* remap tty[ab] to /dev/ttyS[01] */ |
| + | if (strcmp( s, "ttya" )==0) |
| + | console = SERIAL_CON0; |
| + | else if (strcmp( s, "ttyb" )==0) |
| + | console = SERIAL_CON1; |
| + | } |
| #endif | |
| - | } else { |
| - | console = VT_CONSOLE; |
| - | tried_devcons++; |
| + | else { |
| + | struct vt_stat vt; |
| + | static char the_console[13]; |
| + | |
| + | console = the_console; |
| + | /* 2.2 kernels: identify the real console backend and try to use it */ |
| + | if (ioctl(0,TIOCGSERIAL,&sr) == 0) { |
| + | /* this is a serial console */ |
| + | snprintf( the_console, sizeof the_console, "/dev/ttyS%d", sr.line ); |
| + | } |
| + | else if (ioctl(0, VT_GETSTATE, &vt) == 0) { |
| + | /* this is linux virtual tty */ |
| + | snprintf( the_console, sizeof the_console, "/dev/tty%d", vt.v_active ); |
| + | } else { |
| + | console = VT_CONSOLE; |
| + | tried_devcons++; |
| + | } |
| } | |
| while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) { | |
| @@ -219,8 +240,15 @@ static void console_init() | |
| if (fd < 0) | |
| /* Perhaps we should panic here? */ | |
| console = "/dev/null"; | |
| - | else |
| + | else { |
| + | /* check for serial console and disable logging to tty3 & running a |
| + | * shell to tty2 */ |
| + | if (ioctl(0,TIOCGSERIAL,&sr) == 0) { |
| + | log = NULL; |
| + | second_console = NULL; |
| + | } |
| close(fd); | |
| + | } |
| message(LOG, "console=%s\n", console ); | |
| } | |
| @@ -472,7 +500,7 @@ extern int init_main(int argc, char **argv) | |
| if (pid1 == 0 && tty0_commands) { | |
| pid1 = run(tty0_commands, console, wait_for_enter); | |
| } | |
| - | if (pid2 == 0 && tty1_commands) { |
| + | if (pid2 == 0 && tty1_commands && second_console) { |
| pid2 = run(tty1_commands, second_console, TRUE); | |
| } | |
| wpid = wait(&status); | |
| @@ -206,7 +206,7 @@ static char append_char(mode_t mode) | |
| ** | |
| **/ | |
| - | static void list_single(const char *name, struct stat *info) |
| + | static void list_single(const char *name, struct stat *info, const char *fullname) |
| { | |
| char scratch[PATH_MAX]; | |
| short len = strlen(name); | |
| @@ -297,12 +297,12 @@ static void list_single(const char *name, struct stat *info) | |
| wr(name, len); | |
| if (S_ISLNK(mode)) { | |
| wr(" -> ", 4); | |
| - | len = readlink(name, scratch, sizeof scratch); |
| + | len = readlink(fullname, scratch, sizeof scratch); |
| if (len > 0) fwrite(scratch, 1, len, stdout); | |
| #ifdef FEATURE_FILETYPECHAR | |
| /* show type of destination */ | |
| if (opts & DISP_FTYPE) { | |
| - | if (!stat(name, info)) { |
| + | if (!stat(fullname, info)) { |
| append = append_char(info->st_mode); | |
| if (append) | |
| fputc(append, stdout); | |
| @@ -372,7 +372,7 @@ static int list_item(const char *name) | |
| if (!S_ISDIR(info.st_mode) || | |
| (opts & DIR_NOLIST)) { | |
| - | list_single(name, &info); |
| + | list_single(name, &info, name); |
| return 0; | |
| } | |
| @@ -424,7 +424,7 @@ static int list_item(const char *name) | |
| strcpy(fnend, entry->d_name); | |
| if (lstat(fullname, &info)) | |
| goto direrr; /* (shouldn't fail) */ | |
| - | list_single(entry->d_name, &info); |
| + | list_single(entry->d_name, &info, fullname); |
| } | |
| closedir(dir); | |
| return 0; | |