View previous topic :: View next topic |
Author |
Message |
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Sun Jan 26, 2025 6:02 pm Post subject: Script behaviour that is attached to init at master exit |
|
|
My fvwm config start a few bash scripts, and when fvwm exit, one of them, instead of being killed, get lost and the system attach it to pid 1, init. That's on an openrc system.
These 3 scripts are containing a trap command with cleanup function and the same kind of loop
Code: | while :
do
sleep 5
<snip>
done |
I added a test into that while loop that call the cleanup function when 1 is found as its master pid, and it works fine. That script get now killed when fvwn exit.
That show me that the script continue to run when its master process get lost and it get attached to init. Will that be the case on all linux system? _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
sublogic Guru
Joined: 21 Mar 2022 Posts: 303 Location: Pennsylvania, USA
|
Posted: Mon Jan 27, 2025 2:56 am Post subject: Re: Script behaviour that is attached to init at master exit |
|
|
Dominique_71 wrote: | That show me that the script continue to run when its master process get lost and it get attached to init. Will that be the case on all linux system? | Yes, except that a process between fvwm and you could decide to call prctl(PR_SET_CHILD_SUBREAPER, 1 ...), in which case you would be reparented to that process rather than to init.
If you are worried about such craziness, you could test for the ppid to change, rather than hard-coding "1". (That would leave you vulnerable to fvwm crashing just before your script first grabs its parent pid. Okay, test for "changed or equal to 1".) |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Tue Jan 28, 2025 12:18 am Post subject: |
|
|
Thanks for the precision. That will not change much in my case.
It is 3 of these scripts that can be launched by fvwm-crystal. As they are started by fvwm, but fvwm is not their direct parent, I made a helper script that takes the pid of a main script as argument, and return its fvwm parent pid. If it find no fvwm parent, it will stop at pid 1 and return a string.
The 3 main scripts initialise a variable with their fvwm parent pid at startup, and I put a pid test into the while loop. All I have to do is to change that test for pid 1 to a pid change test. As a bonus, an user can use Xephyr to start a second fvwm-crystal instance from the fvwm-crystal menu, and they will not interfere with each others. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 23062
|
Posted: Tue Jan 28, 2025 1:58 am Post subject: |
|
|
The reliable way to handle this would be to use PR_SET_PDEATHSIG to arrange for the kernel to send you a signal when your immediate parent dies. This also avoids polling. You can use the util-linux command setpriv to arrange for a death signal even though you are using shell scripts. |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Tue Jan 28, 2025 11:47 am Post subject: |
|
|
For now I have that:
DesktopCheckParent
Code: |
parent_pid() {
ps -p $(ps -p $(echo $1) -o ppid=) -o pid=
}
top_level_parent_pid() {
Ppid=$(parent_pid $1)
# no infinite loop when no fvwm parent is found:
if [ ${Ppid} -eq 1 ] ; then
echo nofvwmp
exit
fi
if [ "$(ps -p ${Ppid} -o comm=)" == "$2" ] ; then
echo ${Ppid}
exit
else
top_level_parent_pid ${Ppid} ${FvwmExec}
fi
}
search_parent_pid() {
if [ "${FVWM_IS_FVWM3}" == "1" ]; then
FvwmExec="fvwm3"
else
FvwmExec="fvwm"
fi
Pid=${1:-$$}
top_level_parent_pid ${Pid} ${FvwmExec}
}
|
Other script
Code: | #!/usr/bin/env bash
source "${FVWM_SYSTEMDIR}"/scripts/DesktopCheckParent
# be sure no old instance are runninng for the same fvwm parent or with no fvwm parent:
# It should work on linux and freebsd
PFExec="search_parent_pid"
ParentFvwm=$(${PFExec})
for i in $(pgrep -f ScreenLidSuspend) ; do
if [[ $$ -ne ${i} ]] ; then
if [[ ${ParentFvwm} -eq $(${PFExec} ${i}) ]] || [[ "nofvwmp" == "$(${PFExec} ${i})" ]] ; then
kill ${i}
fi
fi
done
# cleanup
cleanup() {
echo cleanup $0
exit 0
}
trap cleanup INT QUIT TERM
# other initialization here
while :
do
# exit if $$ get attached to another parent at fvwm Quit
if [[ "${ParentFvwm}" != "$(${PFExec} $$)" ]] ; then
cleanup
fi
sleep 5
# do something here
done
|
$ParentFvwm is set once for all at the script startup. Inside the while loop, it is compared to a new and current value that will differ from $ParentFvwm only when the script get re-parented. Which imply I don't understand why this is not reliable.
Edit: That should work even in the case Xephyr start a new fvwm instance from the fvwm-crystal menu and at Quit of that second fvwm instance, some process re-parent the script to the first fvwm instance, that because its PID will differ from $ParentFvwm. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
pingtoo Veteran
Joined: 10 Sep 2021 Posts: 1472 Location: Richmond Hill, Canada
|
Posted: Tue Jan 28, 2025 12:10 pm Post subject: |
|
|
Dominique_71,
I can't say I 100% understand your objective. But if my guess is right that you want your process(es) kill when parent (or grand parent) process die. I suggest you can look into sys-process/tini. It can launch your script and arrange to wait for defined parent death signal, And be the sub-reaper to cleanup any sub-processes. Or consider use unshare(1) to a isolated PID namespace for your entire sub-processes group. |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Tue Jan 28, 2025 3:39 pm Post subject: |
|
|
pingtoo wrote: | Dominique_71,
I can't say I 100% understand your objective. But if my guess is right that you want your process(es) kill when parent (or grand parent) process die. I suggest you can look into sys-process/tini. It can launch your script and arrange to wait for defined parent death signal, And be the sub-reaper to cleanup any sub-processes. Or consider use unshare(1) to a isolated PID namespace for your entire sub-processes group. |
Your guess is right.
When the parent (or grand parent) process die, the script get re-parented to another parent process. Which imply that, as I said earlier, I don't get why, to test for a parent process change, is not reliable. Also, the testing I have done showed me that it works fine.
Another concern, as Hu pointed it out: to use another solution may permit to avoid the polling issue. And it look like to be plenty of them. I also found that: https://github.com/taviso/ctypes.sh/wiki
I know by experience that, when it is several solutions to do something, the simplest one is the most reliable most of the time. Which one to choose? _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
pingtoo Veteran
Joined: 10 Sep 2021 Posts: 1472 Location: Richmond Hill, Canada
|
Posted: Tue Jan 28, 2025 3:50 pm Post subject: |
|
|
I think the ctypes.sh is bit of over kill for you objective.
I cannot make recommendation without further understand the flow.
I understand that everything start from "fvwm", however I don't understand how your script(s) got launched. Do they just start with "fvwm" or there is an external event (button clicked for example) that trigger them execution?
Do your script(s) related? one spawn another or just unrelated (i.e. fired in parallel for example) |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Tue Jan 28, 2025 6:37 pm Post subject: |
|
|
Inside fvwm, 2 commands can use /bin/sh (by default). Exec executes commands, and PipeRead executes commands and interpret their output as fvwm configuration sequences on the fly. Both can be launched from anywhere, a menu, a button or an user defined fvwm function, and fvwm will make no distinction and send them to the shell.
With Exec, instead of a & to detach the command, one must use exec. Which gives for theses scripts, things like that:
Code: | Exec exec /usr/share/fvwm-crystal/fvwm/scripts/DesktopCheckMounts 4 |
and:
Code: | $ pstree -a
init
─login --
│ └─bash
│ └─startx /usr/bin/startx
│ └─xinit /home/dom/.xinitrc -- /etc/X11/xinit/xserverrc :0 -auth /tmp/serverauth.d3r0WicYLE
│ ├─X -nolisten tcp :0 -auth /tmp/serverauth.d3r0WicYLE vt1
│ │ └─16*[{X}]
│ └─fvwm3 -v -f /usr/bin/../share/fvwm-crystal/fvwm/config
│ ├─bash /usr/share/fvwm-crystal/fvwm/scripts/AutoHibernate 10 /usr/bin/loginctl
│ │ └─sleep 5
│ ├─bash /usr/share/fvwm-crystal/fvwm/scripts/ScreenLidSuspend /usr/bin/loginctl
│ │ └─sleep 5
│ ├─bash /usr/share/fvwm-crystal/fvwm/scripts/DesktopCheckMounts 4
│ │ └─sleep 4
|
_________________ "Confirm You are a robot." - the singularity
Last edited by Dominique_71 on Tue Jan 28, 2025 7:06 pm; edited 2 times in total |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Tue Jan 28, 2025 6:48 pm Post subject: |
|
|
These scripts are unrelated. They are part of an user preferences system with menu, and at Start, fvwm test and launch only the scripts related to the functions the user want. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Tue Jan 28, 2025 6:55 pm Post subject: |
|
|
And it will be great if it can work on both freebsd and linux.
I will also test on Freesd how I can change the bash shebangs to sh ones, that because FreeBSD's sh is even more restrictive than Debian's dash. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
pingtoo Veteran
Joined: 10 Sep 2021 Posts: 1472 Location: Richmond Hill, Canada
|
Posted: Tue Jan 28, 2025 7:55 pm Post subject: |
|
|
Dominique_71 wrote: | Inside fvwm, 2 commands can use /bin/sh (by default). Exec executes commands, and PipeRead executes commands and interpret their output as fvwm configuration sequences on the fly. Both can be launched from anywhere, a menu, a button or an user defined fvwm function, and fvwm will make no distinction and send them to the shell.
With Exec, instead of a & to detach the command, one must use exec. Which gives for theses scripts, things like that:
Code: | Exec exec /usr/share/fvwm-crystal/fvwm/scripts/DesktopCheckMounts 4 |
and:
Code: | $ pstree -a
init
─login --
│ └─bash
│ └─startx /usr/bin/startx
│ └─xinit /home/dom/.xinitrc -- /etc/X11/xinit/xserverrc :0 -auth /tmp/serverauth.d3r0WicYLE
│ ├─X -nolisten tcp :0 -auth /tmp/serverauth.d3r0WicYLE vt1
│ │ └─16*[{X}]
│ └─fvwm3 -v -f /usr/bin/../share/fvwm-crystal/fvwm/config
│ ├─bash /usr/share/fvwm-crystal/fvwm/scripts/AutoHibernate 10 /usr/bin/loginctl
│ │ └─sleep 5
│ ├─bash /usr/share/fvwm-crystal/fvwm/scripts/ScreenLidSuspend /usr/bin/loginctl
│ │ └─sleep 5
│ ├─bash /usr/share/fvwm-crystal/fvwm/scripts/DesktopCheckMounts 4
│ │ └─sleep 4
|
|
Let me confirm my understand.
From about pstree, it looks to me they were launched by fcwm3 but waiting event(s) right? it is NOT when a event happen then the script get launch right? |
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1802 Location: South America
|
Posted: Tue Jan 28, 2025 9:33 pm Post subject: |
|
|
I see a convoluted (IMO) mechanism being discussed for solving a problem that I also don't understand in general terms. Is the goal having scripts start when fvwm3 starts, run for as long as the fvwm3 process is alive, and exit when it terminates? Why a while do sleep N ... done loop? Are these scripts supposed to wait for some event (as well as the window manager terminating), do something and then wait again? _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
|
|
Back to top |
|
|
pingtoo Veteran
Joined: 10 Sep 2021 Posts: 1472 Location: Richmond Hill, Canada
|
Posted: Tue Jan 28, 2025 10:40 pm Post subject: |
|
|
GDH-gentoo wrote: | I see a convoluted (IMO) mechanism being discussed for solving a problem that I also don't understand in general terms. Is the goal having scripts start when fvwm3 starts, run for as long as the fvwm3 process is alive, and exit when it terminates? Why a while do sleep N ... done loop? Are these scripts supposed to wait for some event (as well as the window manager terminating), do something and then wait again? |
As so far my understanding is OP goal is when fvwm3 dies, all its children should also gracefully terminate.
I think how to make shell script act like daemon is not in OP mind. Dominique_71 please correct me if I am wrong. |
|
Back to top |
|
|
pingtoo Veteran
Joined: 10 Sep 2021 Posts: 1472 Location: Richmond Hill, Canada
|
Posted: Tue Jan 28, 2025 11:02 pm Post subject: |
|
|
Dominique_71 wrote: | And it will be great if it can work on both freebsd and linux.
I will also test on Freesd how I can change the bash shebangs to sh ones, that because FreeBSD's sh is even more restrictive than Debian's dash. |
If my understand was correct then my research find the best method that will work for both FreeBSD and LInux is use "setsid" program.
You should arrange launch your fvwm3 like this Code: | setsid /path/to/fvwm3 -v -f /usr/bin/../share/fvwm-crystal/fvwm/config |
The only caveat is that setsid does not protect the fvwm3 from SIGKILL, therefor if fvwm3 were killed by SIGKILL, its children will remain active.
Now because fvwm3 process is session leader, system will deliver a SIGHUP to its children when fvwm3 die. So you will need to modify your script/program to handle SIGHUP and preform a graceful stop the script/program example shell script: | #!/bin/sh
cleanup() {
# remove temporary file(s)
# close network connection.
]
trap -- "cleanup; exit 0" SIGHUP
while :
do
sleep 5
<snip>
done |
For Linux only,
using tini can work without setsid, so instead launch fvwm3 with setsid, you can keep how fvwm3 launch process as is without change. Just change each script/program launch procedute use Code: | tini -p SIGHUP -s -g -- /path/to/your/script | . Here you script still need to modify to support SIGHUP handle as above. |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Wed Jan 29, 2025 9:37 am Post subject: |
|
|
Yes, I don't want to daemonize these scripts into the system. I just want to be sure they quit or get killed when their parent fvwm instance exit.
And yes, they are launched by fwm, but they look for an event in the system and use /usr/bin/FvwmPrompt (fvwm3) or /usr/bin/FvwmCommand (fvwm2) to send commands to fvwm:
Code: | if [[ "${FVWM_IS_FVWM3}" == "1" ]]; then
FvwmPrompt LoadDesktopIcons
else
FvwmCommand LoadDesktopIcons
fi
|
LoadDesktopIcons is a fvwm-crystal function (user defined fvwm function) that tell fvwm to recalculate and redraw a desktop button with icon launchers. (It takes less resources to make one button with several launchers, than one button per launcher.)
When fvwm read its configuration, it execute it asynchronously with a few exceptions like Piperead and Exec. In
Code: | Exec exec /usr/share/fvwm-crystal/fvwm/scripts/DesktopCheckMounts 4 |
Exec is the fvwm part of the command that tell fvwm to send what's follow to the shell. With exec at the beginning of its command, the shell detach the script. That gives the control back to fvwm, which continue to read and execute its configuration.
In the case of DesktpCheckMounts, the while loop test for changes in mounted partitions, and when such a system event occur, it use FvwmCommand or FvwmPrompt to tell fvwm what to do. Its source: DesktopCheckMounts and the sourced helper: DesktopCheckParent. The final result is something like that: Desktop manager. 2 actions can be set into the button preferences (file managers or custom commands ) and it also support user defined paths (not shown on that picture). _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Wed Jan 29, 2025 9:56 am Post subject: |
|
|
pingtoo wrote: | If my understand was correct then my research find the best method that will work for both FreeBSD and LInux is use "setsid" program.
You should arrange launch your fvwm3 like this Code: | setsid /path/to/fvwm3 -v -f /usr/bin/../share/fvwm-crystal/fvwm/config |
The only caveat is that setsid does not protect the fvwm3 from SIGKILL, therefor if fvwm3 were killed by SIGKILL, its children will remain active. |
It is already the case anyway, even when fvwm quit from its quit menu. That's the reason of the Code: | ps -p $(ps -p $(echo $1) -o ppid=) -o pid= | recursive PID test. It's a terrible hack, but it works with both OS, and from my research, it found no POSIX way to do that at that time. And yes, if I can avoid it, it will be better.
In these scripts previous versions, they was using pid files in /tmp, but that expose their pid into a world writeable place, which is not a best practice. And to make it to work with several fvwm instances would have exposed the fvwm PIDs as well.
With the partition icons, it will be the Penguin invasion on FreeBSD. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
pingtoo Veteran
Joined: 10 Sep 2021 Posts: 1472 Location: Richmond Hill, Canada
|
Posted: Wed Jan 29, 2025 1:03 pm Post subject: |
|
|
Dominique_71 wrote: | pingtoo wrote: | If my understand was correct then my research find the best method that will work for both FreeBSD and LInux is use "setsid" program.
You should arrange launch your fvwm3 like this Code: | setsid /path/to/fvwm3 -v -f /usr/bin/../share/fvwm-crystal/fvwm/config |
The only caveat is that setsid does not protect the fvwm3 from SIGKILL, therefor if fvwm3 were killed by SIGKILL, its children will remain active. |
It is already the case anyway, even when fvwm quit from its quit menu. That's the reason of the Code: | ps -p $(ps -p $(echo $1) -o ppid=) -o pid= | recursive PID test. It's a terrible hack, but it works with both OS, and from my research, it found no POSIX way to do that at that time. And yes, if I can avoid it, it will be better. |
So it apparently it is I missing understand the situation. you already have a solution it just not enough to cover all case.
Since you know fvwm3 process ID, you can use kill -0 <fvwm3 PID> to check if it still exist and react accordingly. |
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1802 Location: South America
|
Posted: Wed Jan 29, 2025 1:39 pm Post subject: |
|
|
Honestly, based on the problem description and my (admittedly superficial) reading of Fvwm's documentation, it looks like modules is the cleanest implementation strategy. Getting end-of-file in the reading pipe signals exit time. Commands can be sent to fvwm3 using the writing pipe. There is some complication because there's also the waiting for system events, but a small program in portable C could handle this on both GNU/Linux and FreeBSD I think. _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
|
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Wed Jan 29, 2025 6:33 pm Post subject: |
|
|
GDH-gentoo wrote: | Honestly, based on the problem description and my (admittedly superficial) reading of Fvwm's documentation, it looks like modules is the cleanest implementation strategy. Getting end-of-file in the reading pipe signals exit time. Commands can be sent to fvwm3 using the writing pipe. There is some complication because there's also the waiting for system events, but a small program in portable C could handle this on both GNU/Linux and FreeBSD I think. |
Modules seam to be an overkill in that case. As fvwm cares and can communicate at any time with them, they will use more resources. The testing I done in the past showed me that each added instance of a fvwm module add resources. A typical example, with fvwm-crystal, is to compare its resources usage between a light recipe (theme) like Clean, and its most complex recipe full of modules, the Amiga one. Nothing catastrophic, but fvwm resource usage increase with the complexity of the in use configuration.
These scripts are a separated story. The are part of functionalities that can be added or not in all recipes from the preferences menu or the exit menu.
For a C program, I know very little of that language, and if someone want to contribute such small programs, I am open. With fvwm3, it is also the possibility, instead of using FvwmPrompt that use the FvwmMFL socket to send commands and communicate with fvwm, to directly send json packets to that socket. These json packets are not documented at that time, and my guess is that they are a work in progress because of current works on the internals of fvwm3 that will change their format, and maybe even some configuration mnemonics. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1802 Location: South America
|
Posted: Wed Jan 29, 2025 8:11 pm Post subject: |
|
|
Dominique_71 wrote: | Modules seam to be an overkill in that case. As fvwm cares and can communicate at any time with them, they will use more resources. |
More resources compared to using Exec, which, if I understand correctly, spawns a not so light shell process? While I don't have experience with Fvwm, it doesn't look like that to me theoretically. On the other hand, again if I understand correctly, they give you a reliable way for knowing when fvwm3 has terminated / restarted / whatever: EOF in the reading pipe. And you get a writing pipe for free for sending commands to fvwm3. _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
|
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Wed Jan 29, 2025 9:32 pm Post subject: |
|
|
pingtoo wrote: |
Since you know fvwm3 process ID, you can use kill -0 <fvwm3 PID> to check if it still exist and react accordingly. |
You are right. I was an idiot when doing that, because even that I didn't paid attention to the -0 kill option before, I didn't searched for something so obvious than a command that can tell me if a given PID is still running or not when I know that PID.
It was the same thing with maths at school. I was really good at it, well enough good to help other peoples to get good at it, and most of my mistakes was so obvious things that I could re-read me 2 or 3 times before giving my copy, that without saying them. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1908 Location: Switzerland (Romandie)
|
Posted: Wed Jan 29, 2025 9:54 pm Post subject: |
|
|
GDH-gentoo wrote: | Dominique_71 wrote: | Modules seam to be an overkill in that case. As fvwm cares and can communicate at any time with them, they will use more resources. |
More resources compared to using Exec, which, if I understand correctly, spawns a not so light shell process? While I don't have experience with Fvwm, it doesn't look like that to me theoretically. On the other hand, again if I understand correctly, they give you a reliable way for knowing when fvwm3 has terminated / restarted / whatever: EOF in the reading pipe. And you get a writing pipe for free for sending commands to fvwm3. |
You must be right. For now, I will incorporate the changes suggested in that discussion, and when done, ask the fvwm workers team what it would takes to made modules out of the result.
But to do it myself would imply for me to really learn the C language, and I already don't have enough time to make what I want to do with fvwm-crystal (FreeBSD support, a key-bindings preferences system, advanced multi-monitor support, a recipe that will let the user design its own desktop themes, these last two tasks can maybe be made or will be best made simultaneously), that it will be much better if I can get help with that and concentrate on the other tasks. _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|