sh(1): add -l option

-l is required by LSB for login shell, all other shells: bash, zsh,
oksh, mksh, ... implements it.

with -l sh will act as a login shell and read the profile.

MFC After: 	1 week
Obtained From:	dash (3b7c8442bfe7c2fd0a6b0415df6ddf66a399fd55)
Reviewed by:	kib, lme
Differential Revision:	https://reviews.freebsd.org/D47681
This commit is contained in:
Baptiste Daroussin 2024-11-20 11:48:39 +01:00
parent 81f7ad324d
commit 65f5dd42f1
4 changed files with 26 additions and 15 deletions

View File

@ -95,6 +95,7 @@ main(int argc, char *argv[])
static struct stackmark smark, smark2;
volatile int state;
char *shinit;
int login;
(void) setlocale(LC_ALL, "");
initcharset();
@ -128,13 +129,13 @@ main(int argc, char *argv[])
initvar();
setstackmark(&smark);
setstackmark(&smark2);
procargs(argc, argv);
login = procargs(argc, argv);
trap_init();
pwd_init(iflag);
INTON;
if (iflag)
chkmail(1);
if (argv[0] && argv[0][0] == '-') {
if (login) {
state = 1;
read_profile("/etc/profile");
state1:

View File

@ -64,7 +64,7 @@ char *nextopt_optptr; /* used by nextopt */
char *minusc; /* argument to -c option */
static void options(int);
static int options(int);
static void minus_o(char *, int);
static void setoption(int, int);
static void setoptionbyindex(int, int);
@ -76,19 +76,20 @@ static int getopts(char *, char *, char **, char ***, char **);
* Process the shell command line arguments.
*/
void
int
procargs(int argc, char **argv)
{
int i;
int i, login;
char *scriptname;
argptr = argv;
login = argptr[0] != NULL && argptr[0][0] == '-';
if (argc > 0)
argptr++;
for (i = 0; i < NOPTS; i++)
optval[i] = 2;
privileged = (getuid() != geteuid() || getgid() != getegid());
options(1);
login |= options(1);
if (*argptr == NULL && minusc == NULL)
sflag = 1;
if (iflag != 0 && sflag == 1 && isatty(0) && isatty(1)) {
@ -119,6 +120,8 @@ procargs(int argc, char **argv)
argptr++;
}
optschanged();
return (login);
}
@ -139,12 +142,13 @@ optschanged(void)
* to the set special builtin.
*/
static void
static int
options(int cmdline)
{
char *kp, *p;
int val;
int c;
int login = 0;
if (cmdline)
minusc = NULL;
@ -190,6 +194,8 @@ options(int cmdline)
if (q == NULL || minusc != NULL)
error("Bad -c option");
minusc = q;
} else if (c == 'l') {
login = 1;
} else if (c == 'o') {
minus_o(*argptr, val);
if (*argptr)
@ -198,13 +204,13 @@ options(int cmdline)
setoption(c, val);
}
}
return;
return (login);
/* When processing `set', a single "-" means turn off -x and -v */
end_options1:
if (!cmdline) {
xflag = vflag = 0;
return;
return (login);
}
/*
@ -217,7 +223,7 @@ end_options2:
if (!cmdline) {
if (*argptr == NULL)
setparam(0, argptr);
return;
return (login);
}
/*
@ -236,6 +242,8 @@ end_options2:
/* We need to keep the final argument */
argptr--;
}
return (login);
}
static void

View File

@ -109,7 +109,7 @@ extern char **argptr; /* argument list for builtin commands */
extern char *shoptarg; /* set by nextopt */
extern char *nextopt_optptr; /* used by nextopt */
void procargs(int, char **);
int procargs(int, char **);
void optschanged(void);
void freeparam(struct shparam *);
int nextopt(const char *);

View File

@ -29,7 +29,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd December 14, 2022
.Dd November 20, 2024
.Dt SH 1
.Os
.Sh NAME
@ -37,14 +37,14 @@
.Nd command interpreter (shell)
.Sh SYNOPSIS
.Nm
.Op Fl /+abCEefhIimnPpTuVvx
.Op Fl /+abCEefhIilmnPpTuVvx
.Op Fl /+o Ar longname
.Oo
.Ar script
.Op Ar arg ...
.Oc
.Nm
.Op Fl /+abCEefhIimnPpTuVvx
.Op Fl /+abCEefhIilmnPpTuVvx
.Op Fl /+o Ar longname
.Fl c Ar string
.Oo
@ -52,7 +52,7 @@
.Op Ar arg ...
.Oc
.Nm
.Op Fl /+abCEefhIimnPpTuVvx
.Op Fl /+abCEefhIilmnPpTuVvx
.Op Fl /+o Ar longname
.Fl s
.Op Ar arg ...
@ -251,6 +251,8 @@ Ignore
from input when in interactive mode.
.It Fl i Li interactive
Force the shell to behave interactively.
.It Fl l
Force the shell to act as if it has been invoked as a login shell.
.It Fl m Li monitor
Turn on job control (set automatically when interactive).
A new process group is created for each pipeline (called a job).