Replace /etc/proper-shells with /etc/proper-sh defaulting to dash.
This commit is contained in:
parent
212539c9de
commit
6bab3819e2
|
@ -157,19 +157,6 @@ diff -Paur --no-dereference -- dash.upstream/src/Makefile.in dash/src/Makefile.i
|
||||||
-rm -f ./$(DEPDIR)/system.Po
|
-rm -f ./$(DEPDIR)/system.Po
|
||||||
-rm -f ./$(DEPDIR)/trap.Po
|
-rm -f ./$(DEPDIR)/trap.Po
|
||||||
-rm -f ./$(DEPDIR)/var.Po
|
-rm -f ./$(DEPDIR)/var.Po
|
||||||
@@ -709,7 +714,11 @@
|
|
||||||
|
|
||||||
info-am:
|
|
||||||
|
|
||||||
-install-data-am: install-man
|
|
||||||
+install-data-am: install-man install-proper-shells
|
|
||||||
+
|
|
||||||
+install-proper-shells:
|
|
||||||
+ mkdir -p "$(DESTDIR)$(sysconfdir)/proper-shells"
|
|
||||||
+ echo dash > "$(DESTDIR)$(sysconfdir)/proper-shells/dash"
|
|
||||||
|
|
||||||
install-dvi: install-dvi-am
|
|
||||||
|
|
||||||
diff -Paur --no-dereference -- dash.upstream/src/miscbltin.c dash/src/miscbltin.c
|
diff -Paur --no-dereference -- dash.upstream/src/miscbltin.c dash/src/miscbltin.c
|
||||||
--- dash.upstream/src/miscbltin.c
|
--- dash.upstream/src/miscbltin.c
|
||||||
+++ dash/src/miscbltin.c
|
+++ dash/src/miscbltin.c
|
||||||
|
|
156
sh/proper-sh.c
156
sh/proper-sh.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2014, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -17,114 +17,84 @@
|
||||||
* Forward execution to the best shell.
|
* Forward execution to the best shell.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
const char* getenv_safe(const char* name, const char* def)
|
static bool is_supported(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
const char* ret = getenv(name);
|
int i;
|
||||||
return ret ? ret : def;
|
for ( i = 1; i < argc; i++ )
|
||||||
}
|
|
||||||
|
|
||||||
bool is_existing_shell(const char* candidate)
|
|
||||||
{
|
|
||||||
pid_t child_pid = fork();
|
|
||||||
if ( child_pid < 0 )
|
|
||||||
return false;
|
|
||||||
if ( !child_pid )
|
|
||||||
{
|
{
|
||||||
close(0);
|
const char* arg = argv[i];
|
||||||
close(1);
|
if ( (arg[0] != '-' && arg[0] != '+') || !arg[1] )
|
||||||
close(2);
|
break; // Intentionally not continue and note '+' support.
|
||||||
open("/dev/null", O_RDONLY);
|
if ( !strcmp(arg, "--") )
|
||||||
open("/dev/null", O_WRONLY);
|
|
||||||
open("/dev/null", O_WRONLY);
|
|
||||||
execlp("which", "which", "--", candidate, (const char*) NULL);
|
|
||||||
exit(127);
|
|
||||||
}
|
|
||||||
int status;
|
|
||||||
waitpid(child_pid, &status, 0);
|
|
||||||
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* search_for_proper_shell(void)
|
|
||||||
{
|
|
||||||
if ( getenv("SORTIX_SH_BACKEND") )
|
|
||||||
{
|
|
||||||
if ( !getenv("SORTIX_SH_BACKEND")[0] )
|
|
||||||
return NULL;
|
|
||||||
if ( is_existing_shell(getenv("SORTIX_SH_BACKEND")) )
|
|
||||||
return strdup(getenv("SORTIX_SH_BACKEND"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* backends_dir_path =
|
|
||||||
getenv_safe("SORTIX_SH_BACKENDS_DIR", "/etc/proper-shells");
|
|
||||||
|
|
||||||
struct dirent** shell_entries;
|
|
||||||
int num_shell_entries = scandir(backends_dir_path, &shell_entries, NULL, alphasort);
|
|
||||||
if ( 0 <= num_shell_entries )
|
|
||||||
{
|
|
||||||
char* result = NULL;
|
|
||||||
for ( int i = 0; i < num_shell_entries; i++ )
|
|
||||||
{
|
|
||||||
struct dirent* entry = shell_entries[i];
|
|
||||||
const char* name = entry->d_name;
|
|
||||||
if ( !strcmp(name, ".") || !strcmp(name, "..") )
|
|
||||||
continue;
|
|
||||||
size_t path_length = strlen(backends_dir_path) + 1 + strlen(name);
|
|
||||||
char* path = (char*) malloc(path_length + 1);
|
|
||||||
if ( !path )
|
|
||||||
continue;
|
|
||||||
stpcpy(stpcpy(stpcpy(path, backends_dir_path), "/"), name);
|
|
||||||
FILE* fp = fopen(path, "r");
|
|
||||||
free(path);
|
|
||||||
if ( !fp )
|
|
||||||
continue;
|
|
||||||
size_t result_size = 0;
|
|
||||||
ssize_t result_length = getline(&result, &result_size, fp);
|
|
||||||
fclose(fp);
|
|
||||||
if ( result_length < 0 )
|
|
||||||
{
|
|
||||||
free(result);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( result[result_length-1] == '\n' )
|
|
||||||
result[--result_length] = '\0';
|
|
||||||
if ( !is_existing_shell(result) )
|
|
||||||
{
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
if ( arg[0] == '+' || arg[1] != '-' )
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
while ( (c = *++arg) ) switch ( c )
|
||||||
|
{
|
||||||
|
case 'e': break;
|
||||||
|
case 'i': break;
|
||||||
|
case 's': break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for ( int i = 0; i < num_shell_entries; i++ )
|
else if ( !strcmp(arg, "--help") )
|
||||||
free(shell_entries[i]);
|
;
|
||||||
free(shell_entries);
|
else if ( !strcmp(arg, "--version") )
|
||||||
if ( result )
|
;
|
||||||
return result;
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return i == argc;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if ( argc == 1 && isatty(0) && isatty(1) )
|
if ( !isatty(0) || !isatty(1) || !is_supported(argc, argv) )
|
||||||
execvp("sortix-sh", argv);
|
{
|
||||||
|
const char* env = getenv("SORTIX_SH_BACKEND");
|
||||||
|
if ( env && env[0] )
|
||||||
|
{
|
||||||
|
execvp(env, argv);
|
||||||
|
if ( errno != ENOENT )
|
||||||
|
err(127, "%s", env);
|
||||||
|
}
|
||||||
|
|
||||||
char* proper_shell = search_for_proper_shell();
|
FILE* fp = fopen("/etc/proper-sh", "r");
|
||||||
if ( proper_shell )
|
if ( !fp && errno != ENOENT )
|
||||||
execvp(proper_shell, argv);
|
err(127, "/etc/proper-sh");
|
||||||
free(proper_shell);
|
if ( fp )
|
||||||
|
{
|
||||||
|
char* proper_sh = NULL;
|
||||||
|
size_t proper_sh_size = 0;
|
||||||
|
ssize_t proper_sh_length = getline(&proper_sh, &proper_sh_size, fp);
|
||||||
|
if ( proper_sh_length < 0 )
|
||||||
|
err(127, "/etc/proper-sh");
|
||||||
|
if ( proper_sh_length && proper_sh[proper_sh_length - 1] == '\n' )
|
||||||
|
proper_sh[--proper_sh_length] = '\0';
|
||||||
|
if ( proper_sh[0] )
|
||||||
|
{
|
||||||
|
execvp(proper_sh, argv);
|
||||||
|
if ( errno != ENOENT )
|
||||||
|
err(127, "%s", proper_sh);
|
||||||
|
}
|
||||||
|
free(proper_sh);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
execvp("dash", argv);
|
||||||
|
if ( errno != ENOENT )
|
||||||
|
err(127, "dash");
|
||||||
|
}
|
||||||
|
|
||||||
execvp("sortix-sh", argv);
|
execvp("sortix-sh", argv);
|
||||||
return 127;
|
err(127, "sortix-sh");
|
||||||
}
|
}
|
||||||
|
|
3
sh/sh.c
3
sh/sh.c
|
@ -2155,7 +2155,10 @@ int main(int argc, char* argv[])
|
||||||
char c;
|
char c;
|
||||||
while ( (c = *++arg) ) switch ( c )
|
while ( (c = *++arg) ) switch ( c )
|
||||||
{
|
{
|
||||||
|
case 'c': flag_c_first_operand_is_command = false; break;
|
||||||
case 'e': flag_e_exit_on_error = false; break;
|
case 'e': flag_e_exit_on_error = false; break;
|
||||||
|
case 'i': flag_i_interactive = false; break;
|
||||||
|
case 's': flag_s_stdin = false; break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c);
|
fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c);
|
||||||
help(stderr, argv0);
|
help(stderr, argv0);
|
||||||
|
|
Loading…
Reference in New Issue