Gtkwialog project

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

Gtkwialog project

#1 Post by wiak »

Gtkwialog is a fork of legacy gtkdialog with some core functionality differences - most of the syntax is identical but not quite all of it. However, 100% legacy gtkdialog compatible (drop-in replacement) mode remains the default. There is also now an additional mode which allows the running of most all legacy gtkdialog apps, whether they use bashisms or not, on for example dash-based systems, without any program modifications required

Since the new version is currently still under development and not yet published, the notes below only cover some of its original extra functionality.

NOTE: Please refer to post three of this thread for 'Some Tips' for using gtkwialog, and post four for a brief explanation of its operational modes: 1. legacy gtkdialog using system() calls; 2. glib spawned command synchronous blocking; 3. glib spawned command asynchronous non-blocking. There are also a couple of simple example posts in post 4 that may be useful for initial testing purposes.


Why gtkwialog was created.

Legacy gtkdialog <action>command_string</action> uses an underlying C system() call, which used the system's /bin/sh -c contruct to parse and run the action command_string in that shell. (Note that /bin/sh -c takes a command_string as an argument, which can be any valid shell commandline). There are some problems with that C system() call strategy, such that many Puppy app/utils are unable to be used on other Linux systems such as Debian, which uses a dash system shell rather than bash. See post two of this thread, below, for more details and how using gtkwialog provides a solution for the problems.


Main early posts about Gtkwialog development started in this thread:

http://www.murga-linux.com/puppy/viewto ... 214#993214

Later I intend to work on the gtkwialog github site, and once I am satisfied the code is working as I intended, I will change the status to alpha release, upload the source file changes, and let you know when that is ready and where it is - the required changes to original gtkdialog only involve a few source files and a less than a dozen lines of code in each, most of which I basically already detailed during development in the above-linked Gtkdialog Tips thread.


DOWNLOAD LINKS: Usual disclaimers apply concerning suitability of purpose.

New version of gtkwialog is under personal testing. New functions include 'mixed mode: allows use of legacy /bin/sh system traditional gtkdialog mode, with the glib -a and -b modes in same dialog. Particularly useful is that newest version still under development allows running most legacy gtkdialog apps, without any modification, on systems that do not use bash as system shell. Exceptions would include apps that use wrong /bin/sh shebang for code that includes bashisms - these will require the small shebang fix when required. Some details of recent testing here:

http://www.murga-linux.com/puppy/viewto ... 007#998007

Having now established that all ideas/elements of the code basically work as intended, I am currently refactoring the code and completing some of the logic selection elements since there is currently too much code duplication due to the way part of legacy gtkdialog is currently organised.

After that, I have to get it all into git resource repository for likely upload thereafter now that this public dev thread has been unlocked. I hope to finish that current dev work (whether the refactoring proves successful or not) within the next week or maybe two.

wiak
Last edited by wiak on Mon 09 Jul 2018, 06:26, edited 48 times in total.

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#2 Post by wiak »

A problem with legacy gtkdialog

Legacy gtkdialog <action>command_string</action> uses an underlying C system() call, which used the system's /bin/sh -c contruct to parse and run the action command_string in that shell. (Note that /bin/sh -c takes a command_string as an argument, which can be any valid shell commandline). There are some problems with that C system() call strategy:

1. It is NOT recommended to use C system() call for mission critical applications owing to security weaknesses in that relatively simple function call:

https://wiki.sei.cmu.edu/confluence/pag ... d=87152177

2. The mechanism always executes that extra process /bin/sh to activate the command, which is wasteful of resource since some form of fork/exec methodology could instead be used without needing an external shell to be run at all.

3. Many current shell/gtkdialog Puppy apps and utils use bash for the script and bash to export the functions with export -f syntax. Unfortunately, when the construct <action>function_name</action> is then used it cannot work if /bin/sh is dash (because only bash can 'see' the exported function code). Hence Puppy (and the Dogs) currently use an ugly hack: they force /bin/sh to be a symlink to bash. Though bash is powerful as a programming shell, and therefore nice to use for programming the front end of a shell/gtkdialog or shell/gtkwialog Puppy/Dog application/utility, it is very inefficient (slow and resource greedy) as a system level non-interactive shell, which is what the Puppy hack forces it to be. That is why pristine/default Debian and Ubuntu use fast, resource-efficient dash shell for system level activities. Unfortunately, the gtkdialog issue described means that the many Puppy/Dog utilities created using bash/gtkdialog in that manner are unable to be run on default Debian or Ubuntu systems (nor on Slitaz, which uses busybox ash as its default system shell).

4. In gtkdialog, all is not what it seems. For example, if a programmer tries to get round the above issue with <action>bash -c "function_name"</action> what really gets run is:

/bin/sh -c 'bash -c "function_name"'

which not only complicates the programmer's eye view of what to expect, but if /bin/sh is dash, it doesn't work because dash doesn't pass on the main bash script's (parent) environment to the bash -c stage.
-----

How gtkwialog avoids all of the above problems:

1. Gtkwialog, removes that insecure /bin/sh -c system() call altogether in its implementation and instead employs a much more sophisticated glib function to parse the <action>command_string</string> and to execute its command contents entirely without any intermediate /bin/sh invocation. Note that a gtkdialog legacy mode is however also provided for backwards compatibility.

2. Furthermore, the construct <action>bash -c "function_name"</action> works with gtkwialog (i.e. the applications bash script exported functions remain visible so it does not matter if on the system, /bin/sh is dash or ash or bash, the construct will still work now.

3. Finally, since there no longer being any underlying /bin/sh process being executed, what the programmer enters into the <action>command_string</action> is what they actually get. So bash -c "function_name" actually means that(!) and no longer actually means /bin/sh -c 'bash -c "function_name"'. All in all that makes debugging and understanding easier as well as not requiring any ugly hack to force /bin/sh to always point to bash. And programs thus created using gtkwialog are thus compatible to run in pristine/default Debian, Ubuntu and similar, where dash (or even ash) is used as the resource efficient system shell.

4. Gtkwialog is also inherently more efficient than gtkdialog since it does not run that unneeded extra /bin/sh process every time an action command is effected.
------

There are one or two differences in using gtkwialog instead of gtkdialog:

1. If using bash exported functions, the action tab must 'always' use the construct 'bash -c' in order that the bash exported environment is visible and the exported function can be found. That 'always' includes for any underlying system shell being used: ash, dash, AND also for when /bin/sh -> bash. You can't leave out the bash -c when using gtkwialog (which you could with gtkdialog using that awful /bin/sh -> bash hack). But consistency is always better than an ugly hack IMO.

2. Since the /bin/sh -c stage is no longer used, there will probably be some subtle differences in how the <action>command_string</action> is parsed and interpreted. No longer do you have to deal with the likes of /bin/sh -c 'bash -c "functionname"'. Instead, with gtkwialog it is, as I said, a case of what you enter as command_string is what you actually get. So the result is that it should actually be 'easier' to get the code correct (including complex shell quoting) when using gtkwialog.

3. The result of the above differences (and perhaps some others, which I don't know) is that gtkwialog is not exactly backwards compatible with gtkdialog code (except when you run it in 'legacy' mode, when it is identical in operation to legacy gtkdialog). But the end result is inherently more secure, more consistent, more efficient, and results in apps which are more portable across Linux systems.

Using bash -c calls may also have security implications, like legacy gtkdialog system() calls (I do not know the ins and outs of that). However, the fact is, a programmer can avoid calling any such construct when using gtkwialog if they so choose. That is in contrast with legacy gtkdialog when any and every action command evokes a /bin/sh shell process via the insecure C system() function call.
-----------------------

The operational modes of gtkwialog

1. if no -a or -b commandline switch then gtkwialog uses legacy gtkdialog mode (in other words a direct replacement using system() command execution same as legacy gtkdialog exactly). For example:

Code: Select all

<action>viewnior &</action>
2. If using gtkwialog -b then you get the same mode in previous gtkwialog which allows bash exported functions to be seen when running underlying non-bash system shells. That uses glib spawned command mode called synchronous (b stands for blocking). To run a command in the background with that mode would require a shell of course since that is a function of a shell to provide job control via &. For example:

Code: Select all

<action>sh -c "viewnior &"</action>
3. If using gtkwialog -a then you get glib spawned command asynchronous, which is non-blocking, meaning the action command returns immediately leaving the command automatically running in the background (without needing a shell process of any kind). For example:

Code: Select all

<action>viewnior</action>
This non-blocking mode may look particularly attractive, which it is for some types of program, but remember the way non-blocking spawned commands immediately return control to the dialog means that some things may not work as expected; for example, refreshing widget variable entries - the command returns immediately but the background command needs time to complete so refresh can happen too early and miss it - programmer has to adjust for that in their <action>commands - for example, maybe wait command, but needs experimentation and up to the script programmer in the end as to when it is appropriate or useful to use this -a mode.

You cannot of course mix modes for the same displayed diagram so programmer chooses which they want for a particular purpose. Of course you could have several dialogs being run from same shell script - each could use different ones of the above modes.

wiak
Last edited by wiak on Sat 02 Jun 2018, 14:55, edited 10 times in total.

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#3 Post by wiak »

Some tips:
rcrsn51 wrote:The good news is, backgrounding appears to work with quoting like this:

Code: Select all

<action>bash -c "FUNC &"</action>
The above (which was using -b for blocking, synchronous gtkwialog mode) is a good example of how the <action>command_string</action> is a case of what you see is correctly (in terms of expected sh commandline use) what you actually get when using gtkwialog.

It the & had been put outside the ("...") quotes then that would of course meant that you were backgrounding the bash -c process rather than the probably intended FUNC you were calling up.
-----

Here is a practical example of converting an existing Puppy/Dog utility with gtkwialog -b mode such that it will also now be compatible with systems not running bash as their /bin/sh system shell:
fredx181 wrote:I took existing script gdrive-gui2 (google-drive filemanager, my mod of mikeb's dropbox_gui) which is pretty complicated and having many "export -f " required functions.
So I changed all exported functions to "bash -c <function>" but one mistake, I made this(setting variable BUTTON):

Code: Select all

<action>BUTTON=3; bash -c add_selection</action>
That didn't work, took me a while to realize it had to be this:

Code: Select all

<action>bash -c "BUTTON=3; add_selection"</action
Ran the script after changing to sh > dash and everything OK.

Also ran the same modified script with sh > bash: also works OK.
To avoid having to type /bin/bash -c often you could simply use:

b="/bin/bash -c"; export b

and then use $b (suitably quoted) in <action>$b rest_of_command_string</action>
---------

If you are worried about using /bin/bash -c constructs in terms of security (which I'm not, but admittedly don't really know the security implications, if any, of using bash -c) then you could use something like step suggested (this being my example to illustrate his excellent algorithm with gtkwialog, here using -b glib command spawning blocking-mode):

Code: Select all

#!/bin/sh 

#Functions 
sub_now (){ 
   date > /tmp/date 
} 
#you avoid using export -f since a bashism 

sub_filemanager (){ 
 pcmanfm & 
} 

#Variables 
program="$0"; export program 

script=' 
<vbox> 
  <entry> 
    <variable>ENTRY_DATE</variable> 
    <input>cat /tmp/date</input> 
  </entry> 
  <button> 
    <label>Refresh</label> 
'"    <action>$program @now</action>  "'
    <action>refresh:ENTRY_DATE</action> 
  </button> 
  <button> 
    <input file stock="gtk-home"></input> 
'"    <action>$program @filemanager</action> "' 
  </button> 
</vbox>' 
export script 

#Main body - this is step's main pattern along with recalling the script 
case $1 in 
@*) sub=sub_${1#@}; shift; $sub "$@"; exit $? ;; # relay sub_func'ions 
# add cases for typical script option parsing, i.e., --help, -x, etc. 
esac 

gtkwialog -b -p script
Note that, in the above, unlike with legacy gtkdialog, with gtkwialog (in -a or -b command spawning modes) no insecure C system() calls are being used at all and also no bash export -f constructs and bash -c construct in this case are needed either.
-------------
rcrsn51 wrote:I am running the 64bit version. The "bash -c FUNC" structure is working correctly, but here is a problem:

Code: Select all

<action>viewnior &</action>
This should pop up a window running viewnior as a backgrounded process.

Instead, viewnior interprets the "&" as a non-existent file, and opens in a non-backgrounded window with a "file not found" message.
@rcrsn51: As I explained, when in standard -b (blocking mode) with gtkwialog, for the above, you need to use <action>sh -c "viewnior &"</action> since it is a shell that provided job control. However:

With the new gtkwialog -a (asynchronous non-blocking mode) you can simply use <action>viewnior</action>. Note however, that legacy gtkdialog always uses blocking-mode, albeit via system() mechanism, so using this gtkwialog -a non-blocking mechanism will not always give expected results with other xml constructs (refreshing widget variables, for example, may not work as expected since non-blocked means instant return. That's not any kind of bug; it is up to the script writer to use -a option only when it is useful (and extra user code can address timing differences anyway), but -b will provide more familiar behaviour. You cannot mix -a and -b on the same dialog of course - but you can have different dialogs in your script, some with -a mode and some with -b mode.

wiak
Last edited by wiak on Tue 29 May 2018, 12:10, edited 16 times in total.

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

The operational modes of gtkwialog

#4 Post by wiak »

SIMPLE PROGRAMS FOR TESTING GTKWIALOG OPERATION:

Just put the appropriate (32bit or 64bit) gtkwialog into your executable PATH first.

Code: Select all

#!/bin/bash

sub_filemanager (){
 rox &
}
export -f sub_filemanager

script='
<vbox>
  <entry>
    <variable>MYENTRY</variable>
    <input>ls -al /bin/sh</input>
  </entry>
  <hbox width-request="480">
    <text><label>Open filemanager:</label></text>
    <button>
      <input file stock="gtk-home"></input>
      <action>bash -c sub_filemanager</action>
    </button>
    <button ok></button>
  </hbox>
</vbox>'
export script

gtkwialog -b -p script
-----

Code: Select all

#!/bin/sh

# Simple Example to show the subtle difference in
# <action>command_strings for the three modes
# available in gtkwialog.
# You can substitute viewnior for gpicview, for example, if you want.
# After you close the first window, the next of the three will open: 

mode_gtkdialog_legacy=' 
<vbox>
  <hbox> 
    <text><label>Open image viewer:</label></text> 
    <button> 
      <input file stock="gtk-home"></input> 
      <action>gpicview &</action> 
    </button> 
    <button ok></button> 
  </hbox>
</vbox>' 
export mode_gtkdialog_legacy 

mode_synchronous_blocking=' 
<vbox> 
  <hbox>
    <text><label>Open image viewer:</label></text> 
    <button> 
      <input file stock="gtk-home"></input> 
      <action>sh -c "gpicview &"</action> 
    </button> 
    <button ok></button> 
  </hbox>
</vbox>' 
export mode_synchronous_blocking 

mode_asynchronous_nonblocking=' 
<vbox> 
  <hbox>
    <text><label>Open image viewer:</label></text> 
    <button> 
      <input file stock="gtk-home"></input> 
      <action>gpicview</action> 
    </button> 
    <button ok></button> 
  </hbox>
</vbox>' 
export mode_asynchronous_nonblocking 

# popup mode_gtkdialog_legacy example window
gtkwialog -p mode_gtkdialog_legacy

# popup mode_synchronous_blocking example window
gtkwialog -b -p mode_synchronous_blocking

# popup mode_asynchronous_nonblocking example window
gtkwialog -a -p mode_asynchronous_nonblocking

exit 0
--------------------------

Trying to see if I can get some of the Gtkdialog Tips example scripts working.

Here are some modded to gtkwialog example scripts that seem to work (will add to these over time). Numbered as in Gtkdialog Tips. Some of these need closed using Ctrl-C from the commandline:

4.) Let external code act on your gtkdialog gui

Code: Select all

#!/bin/sh 

export launch_me=' 
<button> 
 <input file stock="gtk-refresh"></input> 
 <action>Refresh:DATE</action> 
</button>' 

export box=' 
<vbox> 
 <entry><input>date</input><variable>DATE</variable></entry> 
 <button><label>launch</label><action type="launch">launch_me</action></button> 
</vbox>' 

gtkwialog -b -p box
simple example of a clock:

Code: Select all

#!/bin/sh 

export box=' 
 <vbox> 
  <progressbar visible="false"> 
   <input>while [ A != B ]; do sleep 0.5; P=`cat /tmp/p`;   echo $P; echo 100 > /tmp/p; done</input> 
   <action>refresh:ENTRY</action> 
   <action>sh -c "echo 99 > /tmp/p"</action> 
  </progressbar> 
  <entry> 
   <variable>ENTRY</variable> 
   <input>date +%H:%M:%S</input> 
  </entry> 
 </vbox>' 

gtkwialog -b -p box
5.) The benefits of a config file

Set default status of Radiobuttons, Comboboxes..

Code: Select all

#!/bin/bash 
#in case no testc file (first run), build the file 
[ ! -s $HOME/.testrc ] && echo -e -n 'COMBOBOX="item 3"\nENTRY="default text"\nRADIOBUTTON1="false"\nRADIOBUTTON2="true"\n' > $HOME/.testrc 
. $HOME/.testrc 

#define combobox list items 
COMBOBOX_ITEMS="<item>$COMBOBOX</item>" #stored value should be first in list 
for I in 1 2 3 4; do COMBOBOX_ITEMS=`echo "$COMBOBOX_ITEMS<item>item $I</item>"`; done 

export main=" 
<window title=\"The benefits of a config file\"> 
 <vbox> 
  <frame The first item of list is the default choice in a Combobox> 
   <combobox> 
    <variable>COMBOBOX</variable> 
    $COMBOBOX_ITEMS 
   </combobox> 
  </frame> 
  <frame If nothing else is set, the first radiobutton is the active one> 
   <radiobutton> 
    <variable>RADIOBUTTON1</variable> 
    <label>Yes I am</label> 
    <default>$RADIOBUTTON1</default> 
   </radiobutton> 
   <radiobutton> 
    <variable>RADIOBUTTON2</variable> 
    <label>No I'm not</label> 
    <default>$RADIOBUTTON2</default> 
   </radiobutton> 
  </frame> 
  <frame Fetch entry-value from config file> 
   <entry> 
    <variable>ENTRY</variable> 
    <default>$ENTRY</default> 
   </entry> 
  </frame> 
  <hbox> 
   <button ok></button> 
  </hbox> 
 </vbox> 
</window>" 

gtkwialog -bp main > $HOME/.testrc
9.) Tips and tricks

Refresh image

Code: Select all

#!/bin/sh 

export MAIN=' 
<window> 
 <vbox>
  <pixmap> 
   <variable>IMAGE</variable> 
   <input file>/root/image1.png</input> 
  </pixmap> 
  <button> 
   <label>Change image</label> 
   <action>sh -c "cp -f /root/image2*.png /root/image1.png"</action> 
   <action type="refresh">IMAGE</action> 
  </button> 
 </vbox>
</window>' 

gtkwialog -b --center --program=MAIN
Drag'n drop

Code: Select all

#!/bin/bash 
#Code below line 15 (break:) is activated when user move item in list 

ls -1 /usr/share/applications > /tmp/test 
do_something () { Xdialog -info  "Do something with\n$TREE" x 2000 ;} ; export -f do_something 
echo ' 
<vbox> 
   <tree headers-clickable="false" reorderable="true"> 
      <label>Backgrounds</label> 
      <input>cat /tmp/test</input> 
      <output file>/tmp/test</output> 
      <variable>TREE</variable> 
      <height>300</height><width>200</width> 
      <action>bash -c "do_something &"</action> 
      <action signal="button-release-event" condition="command_is_true( echo $PTR_Y )">break:</action> 
      <action signal="button-release-event">save:TREE</action> 
      <action signal="button-release-event">activate:BTN_SAVE</action> 
   </tree> 
   <button visible="false"> 
      <variable>BTN_SAVE</variable> 
      <action>cp /tmp/test /tmp/testbackup</action> 
      <action>save:TREE</action> 
      <action condition="command_is_true([[ $(wc </tmp/test) != $(wc </tmp/testbackup) ]] && sed \"s/^|*//\" /tmp/testbackup > /tmp/test && echo true )">refresh:TREE</action> 
   </button> 
</vbox>' | gtkwialog -b -s
For the record, we keep the old solution for this task...

Code: Select all

#!/bin/bash 

move (){ 
   PRESS_EVENT=$(cat /tmp/PRESS_EVENT) 
   [[ $PRESS_EVENT && $TREE ]] || exit #exit if at least one of the 2 values is empty 
   [[ $PRESS_EVENT == $TREE ]] && exit #exit if both are equal (=single or double click) 
   sed -i "/$PRESS_EVENT/d; /$TREE/ i\\$PRESS_EVENT" /tmp/list #remove PRESS_EVENT, then insert item PRESS_EVENT before item $TREE 
} 
export -f move 

ls -1 /usr/share/applications > /tmp/list 

export test=" 
<tree rules_hint=\"true\" hover-selection=\"true\" tooltip-text=\"Drag'n drop items to move them in list\"> 
 <label>Backgrounds</label> 
 <input>cat /tmp/list</input> 
 <variable>TREE</variable> 
 <height>300</height><width>200</width> 
 <action signal=\"button-press-event\">sh -c \"echo \$TREE > /tmp/PRESS_EVENT\"</action> 
 <action signal=\"button-release-event\">bash -c move</action> 
 <action signal=\"button-release-event\">refresh:TREE</action> 
</tree>" 
gtkwialog -bp test
Let entry accept (some) numbers only

Code: Select all

#!/bin/bash 
  
export MAIN_DIALOG=' 
<vbox> 
    <text> 
      <label>"Enter a number (text will default to 0)"</label> 
    </text> 
    <entry editable="true" allow-empty="false"> 
      <input>case $ENTRY in ""|*[^0-9]*) echo 0;; *) echo $ENTRY ;; esac</input> 
      <variable>ENTRY</variable> 
      <action signal="focus-out-event">refresh:ENTRY</action> 
    </entry> 
    <text> 
      <label>"Enter a number within [5,15], otherwise: 
        input will be capped at 15, 
        floored at 5, 
        or set to 10 in case of text input"</label> 
    </text> 
    <entry editable="true" allow-empty="false"> 
      <input>A=$ENTRY2; case $A in [0-9]*) [[ $A -gt 15 ]] && echo 15 || [[ $A -lt 5 ]] && echo 5 || echo $A ;; *) echo 10;; esac</input>
      <variable>ENTRY2</variable> 
      <action signal="focus-out-event">refresh:ENTRY2</action> 
    </entry> 
  <button ok></button> 
</vbox>' 

gtkwialog -b -p MAIN_DIALOG 
unset MAIN_DIALOG
Use a splash screen

Code: Select all

#!/bin/sh 

#Splash 
echo 0 > /tmp/splash 
export SPLASH=' 
<window title="PCC" icon-name="gtk-preferences" resizable="false" decorated="false">'" 
<vbox> 
 <pixmap><input file>/usr/share/icons/hicolor/48x48/apps/wex48.png</input></pixmap> 
 <text height-request=\"50\" use-markup=\"true\"><label>\"<b><span size='"'x-large'"' color='"'orange'"'>Puppy Control Center</span></b>\"</label></text>"' 
 <progressbar visible="true"> 
  <label>nn</label> 
  <input>while [ "$M" != "100" ]; do M=$(cat "/tmp/splash"); [ "$M" != "100" ] && M=$(( M + 4 )); echo "$M"|tee "/tmp/splash"; sleep 1; done</input>
  <action type="exit">Ready</action> 
 </progressbar> 
</vbox></window>' 
gtkwialog -bp SPLASH --center & 

sleep 10 #well, this is to simulate some startup processes.... 

export GUI=' 
<window title="PCC" icon-name="gtk-preferences" width-request="800"> 
<vbox> 
  <text height-request="200"> 
   <label>Hello, welcome to the Puppy Control Center</label> 
  </text> 
  <hbox> 
    <button ok>
    </button> 
  </hbox> 
</vbox> 
</window>' 

gtkwialog -bp GUI
echo 100 >/tmp/splash
sleep 1
rm /tmp/splash
Last edited by wiak on Sat 02 Jun 2018, 15:07, edited 13 times in total.

User avatar
rcrsn51
Posts: 13096
Joined: Tue 05 Sep 2006, 13:50
Location: Stratford, Ontario

#5 Post by rcrsn51 »

I am running the 64bit version. The "bash -c FUNC" structure is working correctly, but here is a problem:

Code: Select all

<action>viewnior &</action>
This should pop up a window running viewnior as a backgrounded process.

Instead, viewnior interprets the "&" as a non-existent file, and opens in a non-backgrounded window with a "file not found" message.

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#6 Post by wiak »

rcrsn51 wrote:

Code: Select all

<action>viewnior &</action>
This should pop up a window running viewnior as a backgrounded process.

Instead, viewnior interprets the "&" as a non-existent file, and opens in a non-backgrounded window with a "file not found" message.
Well, that is to be expected for that kind of example. There is no shell process ever started up by gtkwialog itself (unlike C system() call method of legacy gtkdialog). The action command_string is simply parsed (as if by a UNIX shell, but actually just by a function) and the command then run (fork/executed). It is up to the programmer if they want to use & (which needs a shell process for backgrounding as part of the overall <action>command_string</action>):

Code: Select all

<action>sh -c "viewnior &"</action>
or simpler is just like at the commandline:

Code: Select all

<action>sh -c viewnior &</action>
I'd have to ponder what the difference is, but it is just commandline syntax - nothing particularly to do with gtkwialog.

EDIT: For example, compare the different result of:

Code: Select all

<action>sh -c "sleep 10" &</action>
and

Code: Select all

<action>sh -c "sleep 10 &"</action>
in terms of watching the processes in action with LxTask or similar. I think the first one actually backgrounds the whole shell command (which can't return till the sleep finishes) whilst the second just backgrounds the sleep process running within the shell (and therefore can return leaving the sleep running in the background) (?)

As I said, with gtkwialog, what you enter is what you get. You need to run a shell if you want to background a command. I am sure you know that job control is one of the main usual functions of a shell.

User avatar
rcrsn51
Posts: 13096
Joined: Tue 05 Sep 2006, 13:50
Location: Stratford, Ontario

#7 Post by rcrsn51 »

Here is my understanding of the security issue (but I could be wrong):

Using system() is insecure because the command runs in a shell that inherited the parent's environment. If a malicious user inserted something bad into the environment, it could alter how the command runs.

Using fork()+execve() is more secure because the parent can sanitize the environment that it passes to the forked child process.

But it is the responsibility of the parent program to provide that sanitizing code. In the case of gtkwialog, it doesn't know in advance what command is going to run and what sanitizing is required.

So I suspect that gtkwialog just passes along its own parent's environment. In which case, it is no more secure than system().

User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

#8 Post by misko_2083 »

wiak wrote:
rcrsn51 wrote: EDIT: For example, compare the different result of:

Code: Select all

<action>sh -c "sleep 10" &</action>
and

Code: Select all

<action>sh -c "sleep 10 &"</action>
in terms of watching the processes in action with LxTask or similar. I think the first one actually backgrounds the whole shell command (which can't return till the sleep finishes) whilst the second just backgrounds the sleep process running within the shell (and therefore can return leaving the sleep running in the background) (?)
Speaking of sleep, if next action is run from a button put geany on top of gtkwialog window and then gtkwialog is put back in focus, gtkwialog will be empty/unusable until the sleep ends. It seems the window is being redrawn only when the command ends.

Code: Select all

<action>bash -c "geany & sleep 10;"</action>
Next command will make it unusable until geany is closed.

Code: Select all

<action>bash -c "geany & wait $!"</action>

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#9 Post by wiak »

misko_2083 wrote: Speaking of sleep, if next action is run from a button put geany on top of gtkwialog window and then gtkwialog is put back in focus, gtkwialog will be empty/unusable until the sleep ends. It seems the window is being redrawn only when the command ends.

Code: Select all

<action>bash -c "geany & sleep 10;"</action>
Next command will make it unusable until geany is closed.

Code: Select all

<action>bash -c "geany & wait $!"</action>
But, to me, this is just 'normal' expected commandline process behaviour. In the first of the above, you run geany and background it, but you also run a 10 second sleep without backgrounding it. bash cannot return to the commandline till its child sleep process is finished. (That reflects in the gtkwialog GUI being inactive till bash returns).

Similarly for your second example; try at a console commandline:

Code: Select all

geany & wait $!
The result is to be expected (bash has to wait till its child process, geany, completes before can return). Just normal shell process handling, not a feature or disadvantage of gtkwialog.

Like I said, what you put in is what you get in terms of correct shell/process behaviour. Of course working out what the shell is going to do with complex commands is often more than a bit tricky but you can just try the commands at the commandline first before using inside gtkwialog <action> tags.

EDIT: In both legacy gtkdialog and gtkwialog the <action> command is blocked unless told to background. That's part of C system() functionality (waits till child process started finished) and also part of glib's g_spawn_command_line_sync function I use in gtkwialog as an alternative. I did try a version of that command that does not block waiting by the way, but I decided to mimic gtkdialog as much as possible in that way in order for Refresh widget timings to work the same. I may experiment with that non-blocking version too sometime - the problem becomes how to block when you want to and wait construct with sh might do that job in that case right enough.

wiak
Last edited by wiak on Sun 27 May 2018, 16:44, edited 1 time in total.

User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

#10 Post by misko_2083 »

wiak wrote: But, to me, this is just 'normal' expected commandline process behaviour. In the first of the above, you run geany and background it, but you also run a 10 second sleep without backgrounding it. bash cannot return to the commandline till its child sleep process is finished. (That reflects in the gtkwialog GUI being inactive till bash returns).

Similarly for your second example; try at a console commandline:

Code: Select all

geany & wait $!
The result is to be expected (bash has to wait till its child process, geany, completes before can return). Just normal shell process handling, not a feature or disadvantage of gtkwialog.

wiak
I thought it would disable the button until the process is terminated. :)

So if there are more commands of which none should wait, just fork them all.

Code: Select all

bash -c "(geany & sleep 10; echo hi) &"

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#11 Post by wiak »

misko_2083 wrote:
So if there are more commands of which none should wait, just fork them all.

Code: Select all

bash -c "(geany & sleep 10; echo hi) &"
Exactly. By the way I did EDIT and add a bit of explanation in previous post (whilst you were posting):

This bit I mean:

EDIT: In both legacy gtkdialog and gtkwialog the <action> command is blocked unless told to background. That's part of C system() functionality (waits till child process started finished) and also part of glib's g_spawn_command_line_sync function I use in gtkwialog as an alternative. I did try a version of that command that does not block waiting by the way, but I decided to mimic gtkdialog as much as possible in that way in order for Refresh widget timings to work the same. I may experiment with that non-blocking version too sometime - the problem becomes how to block when you want to and wait construct with sh might do that job in that case right enough. EDIT2 But I had my doubts and so moved on without further consideration.

User avatar
fredx181
Posts: 4448
Joined: Wed 11 Dec 2013, 12:37
Location: holland

#12 Post by fredx181 »

Hi wiak,

Tested now on 64-bit, using the same script I modified for use with gtkwialog (google-drive filemanager) as I described in the other thread and results are the same, all working as expected.
Also tested "debdog-install", don't know if it's useful info, anyway I knew already (by testing earlier) that it works OK also in case dash > sh, out of curiosity replaced in the script the gtkdialog instances with gtkwialog, ran it and works fine.

Thanks again for your efforts !

Fred

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#13 Post by technosaurus »

One of the shortcomings of gtkdialog is its limited support for gtkbuilder files (the xml output by current versions of Glade) mostly because gtkdialog predates the introduction of gtkbuilder. I looked into adding it previously, but I got frustrated by gtk's lack of thought regarding the creation of the whole builder infrastructure - there is(was?) no generic way to interact with components, so each action needed its own c function - which isn't very useful for something like gtkdialog. If you could figure that out, more people would be able to contribute by using Glade to tweak the interface. It may be more advanced than what you want to do now, but its something to keep in the back of your mind.

FWIW, using the glib spawn functions instead of system and popen, may make gtkwialog portable to windows if anyone wants to give it a go.

Edit: here is a link to the conveniently forgotten gtk bug
https://web.archive.org/web/20100510072 ... bleSignals
BTW, this is one of many reasons I stopped using gtk. If Redhat doesn't use it for their enterprise distro, it gets dropped.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#14 Post by wiak »

Apparently continuing to be discussed on wrong thread; sorry, again, for somewhat clogging up Gtkdialog Tips thread:

http://www.murga-linux.com/puppy/viewto ... 539#993539

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#15 Post by wiak »

Though I'd like to modify all or most of my own shell/gtkdialog apps such that they use gtkwialog, I don't know when or if I will get round to all of that. I am not myself too happy having to have two gtk...dialog apps required on my system, so I've been working on ways round that issue throughout today. I've done half the coding involved in that, but haven't finished details as yet. None of what I'm doing (currently) effects operation of gtkwialog otherwise though - so nothing new needed testing anyway for now. Nor am I trying to compete with Puppy's gtkdialog or replace it - fact is, now that I'm working on gtkwialog there may well be some ideas I want to try in it that gtkdialog maintainers would not be happy with there anyway. Which is another reason I rightly or wrongly chose to fork and rename, but whether I am justified to publish the fork is another matter and I'm not sure I really care about that matter.

Disciple is/seems a nice guy and meant no harm in a few comments he wrote; I understand that (and indeed, the overall impression was that he was keen that Puppy adopt gtkwialog approach, albeit not forked), but, sorry, I do expect actual trouble from some on this forum. Whether everyone would like to adopt gtkwialog 'approach' is another matter (and no concern of mine per se); this is Puppy forum... so I doubt that very much, and may be there are good reasons not to (I am not stating an opinion).

I'll keep on with my coding, and see how it goes. Actually, I'm planning to incorporate (via commanline switches) several difference mechanisms into my experimental version, because there is a non-blocking (rather than existing blocking) glib spawn mechanism (including the gtkdialog original) that I'd like to have available for use at times too (I've already tried it). When using that non-blocking mechanism I (think) I will no longer need to use a shell to effect backgrounding (&) operation.

EDIT: Basically, in more detail, my plan (started to be actioned early today following some thought about the needs and hows) is that with appropriate commandline switch gtkwialog will use (my favourite) glib blocking spawn mechanism (like current gtkwialog, so just a minor operational change - a gtkwialog --switch [-b] will be needed on commandline) and with other commandline switch [-a] will instead use glib unblocking spawn mechanism (to hopefully allow &-like backgrounding without needing shell process) and for no extra commandline switch, it will use legacy-compatible mechanism (which some might find contentious). But now, and 'maybe later', I like that the slightly different name differentiates from legacy versions - at least the user is then clear on the different facilities that are available. Furthermore, I may well want to diverge in functionality further from legacy gtkdialog (Puppy gtkdialog may want to diverge in ways I don't) - For now, I'll just do all these things for my own experiment/versions to avoid the dangers of tinkering with official code (and I don't want to ask permission to have my ideas approved by some authority - this is just an experimental fork for my own home desired purposes actually.

However, more than these simple additions I really, on the whole, do not 'intend' adding any further extra ever (though as I've said it is dodgy to ever say never is never). Main thing is I don't want to add bloat and I want backward's compatibility (as far as I technically can manage, which seems likely to me in this case), and stability - too much change is a bad thing I feel (I'm getting old?). I'm tired now (always tired these days) so will hang up the computer for a little while now (as long as my addiction allows me that escape anyway).

wiak
Last edited by wiak on Mon 28 May 2018, 13:38, edited 3 times in total.

User avatar
rcrsn51
Posts: 13096
Joined: Tue 05 Sep 2006, 13:50
Location: Stratford, Ontario

#16 Post by rcrsn51 »

Hi wiak: This may already have been discovered way back when the "exported functions" issue was first discussed in the Dog threads. But some random googling found this.

Note how "/bin/sh" is baked into the system() function. That suggests that in order for a legacy gtkdialog app (with exported functions) to run in a non-bash environment, /bin/sh would need to be re-linked to /bin/bash.

Meaning that you would effectively have to force the whole environment back into bash.

Bill

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#17 Post by wiak »

Hi Bill,

I'm not sure what you are getting at. As you know I've stated already how C system() call uses /bin/sh -c (I've read the source code already).

http://www.murga-linux.com/puppy/viewto ... 108#993108

That indeed is why exported bash functions (using export -f) can only be used with legacy gtkdialog when /bin/sh is forcibly symlinked to bash. Fred did try some techniques to automate that for only when legacy gtkdialog app was actually running, and whilst his attempt seemed promising at the time, it ended with some show-stopper or other. You'd have to ask Fred more about that one since I've forgotten the link and details.

Oh here it is, Fred mentioned his attempt more recently in same thread as above link:
Fred wrote:But don't get me wrong, I'd love to have it like standard Debian with sh > dash, maybe you remember I've tried in the past by using "switchsh", but didn't work out.

http://murga-linux.com/puppy/viewtopic. ... 995#924995
wiak

User avatar
rcrsn51
Posts: 13096
Joined: Tue 05 Sep 2006, 13:50
Location: Stratford, Ontario

#18 Post by rcrsn51 »

wiak wrote:I'm not sure what you are getting at.
I guess that I am just confirming what has now become evident.

1. Trying to port legacy gtkdialog apps into non-bash environments is a dead-end.

2. Gtkwialog will provide a solution for those who want that ability.

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#19 Post by wiak »

New prealpha for testing only version of gtkwialog released which gets rid of the need to have two versions of gtk...ialog on your system since it includes optional gtkdialog command execing mode. Preferred mode, however, is to use with -b switch, which results in same glib command spawning mode as used in previous gtkwialog release: that is the mode that allows export -f to work with underlying dash shell etc.

Download link at first post of this thread.
wiak wrote: New versions, which will use legacy gtkdialog mode (which uses system() call) if no commandline switch -b or -a provided:

NOTE WELL: The usual preferred mode is however to generally to use with -b switch as described below.

Compiled on XenialDog64 and XenialDog32

gtkwialog_prealpha64n (64bit version):

gtkwialog_prealpha32n (32bit version):



To get gtkwialog mode of previous release, you need to run the command with

Code: Select all

gtkwialog -b
followed by any other gtkwialog options you need (such as -p)

The -b stands for use 'blocking', which uses glib sync mode command spawning.

Alternatively, if you run it with:

Code: Select all

gtkwialog -a etc...
The -a stands for use (non-blocking) glib async mode command spawning (which can start up a program in the background without needing shell & symbol. However, that mode returns immediately, which will likely not be desired response with most legacy bash/gtkdialog apps).
Only if you really know what you are doing, and at your own risk: You should be able to replace your existing legacy gtkdialog binary and use this one instead (perhaps via gtkdialog as symlink to gtkwialog) and existing shell/gtkdialog apps should work out of the box. However, new apps or modded apps are recommended to use the -b switch to put gtkwialog into glib sync command spawning blocking mode (which is mode used in previous gtkwialog release). DISCLAIMER: I am not suggesting you do replace your existing gtkdialog - this release of gtkwialog is indicated as being prealpha on purpose - it is not any kind of official release; only for testers who know what they are doing. Per the usual disclaimers and caveats, the program is not guaranteed to be fit for purpose. However, working fine in all my own tests so far.

At least the different name, "Gtkwialog", also removes the confusion some people have between legacy "Gtkdialog", the GUI building utility, and GtkDialog the name of the Gtk library code that provides the underlying functionality... i.e. comments I've read, such as: oh, I though gtkdialog was provided as part of Gtk ;)

As far as further development is currently concerned: All going well, the only thing left to be done is to update the help text for gtkwialog --help. Obviously I don't want to muck with that yet until program testing shows all good.
rcrsn51 wrote:I am running the 64bit version. The "bash -c FUNC" structure is working correctly, but here is a problem:

Code: Select all

<action>viewnior &</action>
This should pop up a window running viewnior as a backgrounded process.

Instead, viewnior interprets the "&" as a non-existent file, and opens in a non-backgrounded window with a "file not found" message.
@rcrsn51: As I explained, when in standard -b (blocking mode) with gtkwialog, for the above, you need to use <action>sh -c "viewnior &"</action> since it is a shell that provided job control. However:

With the new gtkwialog -a (asynchronous non-blocking mode) you can simply use <action>viewnior</action>. Note however, that legacy gtkdialog always uses blocking-mode, albeit via system() mechanism, so using this gtkwialog -a non-blocking mechanism will not always give expected results with other xml constructs (refreshing widget variables, for example, may not work as expected since non-blocked means instant return. That's not any kind of bug; it is up to the script writer to use -a option only when it is useful (and extra user code can address timing differences anyway), but -b will provide more familiar behaviour. You cannot mix -a and -b on the same dialog of course - but you can have different dialogs in your script, some with -a mode and some with -b mode. Lots to try out and test...

Note that I've slightly modified post three ("Some tips") of this thread to account for the new -a and -b command spawn modes of gtkwialog.

wiak

darry19662018
Posts: 721
Joined: Sat 31 Mar 2018, 08:01
Location: Rakaia
Contact:

#20 Post by darry19662018 »

Hi Wiak,

I have made a Wiki entry for Gtkwialog.
http://www.puppylinux.org/wikka/Gtkwialog

Any changes you wish made to the entry please let me know.

Post Reply