if source command.sh issue

2024-09-04 Thread morshalev
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu' 
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
-DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  -D_GNU_SOURCE -DRECYCLES_PIDS 
-DDEFAULT_PATH_VALUE='/usr/local/bin:/usr/bin'  -DSYSLOG_HISTORY -O2 -g -pipe 
-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS 
-fexceptions -fstack-protector-strong -grecord-gcc-switches 
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic 
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection 
-Wno-parentheses -Wno-format-security
uname output: Linux morsh.c.edafarm-workstations-prod.internal 
4.18.0-513.11.1.el8_9.0.1.x86_64 #1 SMP Sun Feb 11 10:42:18 UTC 2024 x86_64 
x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 4.4
Patch Level: 20
Release Status: release

Description:
script.sh contain:
if source command.sh ; then
  echo pass
else
  echo fail
fi

command.sh contain 'set -e' at start. so command.sh should exit once detect 
fail.

once calling ./script.sh it look like command.sh dont handle 'set -e' correctly 
and it continue the script till the end anyway. (btw, it works correctly at 
version 4.2.46(2)-release (x86_64-redhat-linux-gnu)

Repeat-By:
[Describe the sequence of events that causes the problem
to occur.]

Fix:
[Description of how to fix the problem.  If you don't know a
fix for the problem, don't include this section.]



Re: Feature request: process title with exec -a "" for oneself

2024-09-04 Thread Chet Ramey

On 8/31/24 10:43 PM, Lockywolf wrote:

Dear Bash developers,

May I ask for a small feature to be added to bash?

At the moment exec changes IO redirections for the newly started
processes, but if there is no command for exec'ing, it changes those
redirections for the bash process itself.

The exec -a, however, allows setting the current process title (argv0)
only for the newly exec'ed processes, and "exec -a whatever" (without a
command) does nothing.

However it seems to be possible (albeit in a series of 8 syscalls) to
change the _current_ process' cmdline and argv0:


Currently, the shell's argc/argv are exposed to the user as

$1...$n - the positional parameters (argv[1]...argv[argc])
$# - the number of positional parameters (argc)
$0 - argv[0]

You can change the positional parameters and $# using the `set' builtin,
and, in bash versions newer than bash-4.4, you can change $0 by assigning
to BASH_ARGV0.

So I assume that you want to change the kernel's idea of the process
arguments as seen and displayed by `ps'. If so, I'm not really interested
in adding that as a feature. It doesn't seem to add anything for shell
users.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: if source command.sh issue

2024-09-04 Thread Robert Elz
Date:Wed, 24 Jul 2024 13:22:07 + (UTC)
From:morshalev@morsh.c.edafarm-workstations-prod.internal
Message-ID:  
<20240904151336.D40A9142EBC@morsh.c.edafarm-workstations-prod.internal>

There is no bug here.

  | if source command.sh ; then

  | command.sh contain 'set -e' at start. so command.sh should exit once detect 
fail.

Once again, -e is bizarre, and stupid, and really shouldn't be used
almost anywhere.

Here the issue is that when a command is run as the condition of
an "if" -e doesn't apply (you wouldn't want it to).   What people
fail to understand is that this applies to absolutely everything
in a function, or source'd script - -e simply does not apply if
you use it in a context like that (or one of the others where
-e is inapplicable).

Just find another way, avoid -e, you'll waste much less time
than attempting to fight against the -e rules in order to save
yourself some effort checking that everything which should work
does work.   The latter seems like it should be harder when you
start out ("-e will just solve all that") but it *never* turns out
that way.

kre





Re: Feature request: process title with exec -a "" for oneself

2024-09-04 Thread Emanuele Torre
I think your idea of using  exec -a ''  with no positional arguments to
set it is pretty cool, since  exec -a  changes the argv[0] of the
invoked process and exec with redirections an no arguments applies
redirections to the current shell permanently!

Not super relevant, but I have a bash loadable builtin that can set the
script's proctitle that I wrote for fun ~1 year ago.

It has to use an hack to figure out the right offset of argv[0]: it
abuses the fact that the global variable  shell_name  is always set to a
pointer that is an offset into argv[0], so walking backwards from it
until a NUL is reached finds the start of argv[0].

But, otherwise, it works fairly well; you can also unload it to restore
the original proctitle (enable -d setproctitle), and reload it to change
it again.

I was aware of the prctl(PR_SET_MM_ARG_{START,END}) approach, but I have
never personally tried it.  It does sound like a cleaner approach
though, especially since bash doesn't easily expose argv[0], and we have
to resort to an hack to find it; perhaps you could write your own
loadable builtin that uses that. ^^

I left my loadable builtin at the bottom of the email.

o/
 emanuele6

Build with:

  make CFLAGS="$(pkg-config --libs --cflags bash) -shared" setproctitle

Load with  enable -f ./setproctitle setproctitle

 setproctitle.c 
#include 
#include 

#include 

#include 
#include 
#include 
#include 

static char *memstart = NULL;
static char *memend = NULL;
static char *memstart_copy = NULL;
static char *original_shell_name = NULL;

static size_t
count_bytes(char const *const path)
{
size_t size = 0;

int fd;
do {
fd = open(path, O_RDONLY);
} while (fd < 0 && errno == EINTR);
if (fd < 0) {
builtin_warning("%s: Open error: %s", path, strerror(errno));
return size;
}

ssize_t nread;
do {
char buf[PIPE_BUF];
nread = read(fd, buf, sizeof buf);
if (nread > 0)
size += nread;
} while (nread > 0 || (nread != 0 && errno == EINTR));
if (nread < 0)
builtin_warning("%s: Read error: %s", path, strerror(errno));

int ret;
do {
ret = close(fd);
} while (ret < 0 && errno == EINTR);
if (ret < 0)
builtin_warning("%s: Close error: %s", path, strerror(errno));

return size;
}

int
setproctitle_builtin_load(char const *const name)
{
(void)name;

/* shell_name is always an offset into argv[0] */
memstart = shell_name;
/* find the start of argv[0]; linux seems fine with this approach */
while (memstart[-1])
--memstart;

/* save and copy shell_name to the heap */
memstart_copy = savestring(memstart);
original_shell_name = shell_name;
shell_name = &memstart_copy[shell_name - memstart];

/* figure out size of usable memory counting bytes in
   /proc/self/cmdline and /proc/self/environ */
memend = memstart;

memend += count_bytes("/proc/self/cmdline");
memend += count_bytes("/proc/self/environ");

/* fallback to length of argv[0] in case that does not work... */
if (memend == memstart)
memend += strlen(memstart) + 1;

return 1;
}

void
setproctitle_builtin_unload(char const *const name)
{
(void)name;

/* restore shell_name */
(void)strcpy(memstart, memstart_copy);
shell_name = original_shell_name;
xfree(memstart_copy);
}

static int
setproctitle_builtin(WORD_LIST *list)
{
if (no_options(list))
return EX_USAGE;
list = loptend;

(void)memset(memstart, 0, memend - memstart);
char *memused = memstart;
for (WORD_LIST const *l = list; l; l = l->next) {
size_t const maxlen = memend - memused - 1;
char const *const arg = l->word->word;
size_t const len = strlen(arg);
if (len > maxlen) {
builtin_warning("Too long, trimming...");
(void)memcpy(memused, arg, maxlen);
break;
}
(void)memcpy(memused, arg, len);
memused += len;
}

return EXECUTION_SUCCESS;
}

static char *setproctitle_doc[] = {
"Changes the shell's proctitle",
"",
"If multiple arguments are passed, they are concatenated.",
"",
"Exit Status:",
"Always returns 0 if the command is valid.",
NULL,
};

struct builtin setproctitle_struct = {
"setproctitle",
setproctitle_builtin,
BUILTIN_ENABLED,
setproctitle_doc,
"setproctitle [title ...]",
0,
};