How do I conditionally use threads in a perl script? - multithreading

I have a perl script that I've developed that runs on hosts that have different versions of perl, sometimes compiled with threads and sometimes without.
I have a
use if $Config{"useithreads"}, "threads";
And all of my thread-specific code is in similar conditionals.
However, during the compile phase, perl still chokes on threads::all, threads::running, etc.
How can I unsure my script runs on both threaded and non-threaded perls?
[ worr on worr-mn1 ] ( manage_usr_local_admin ) % perl -c acct_mgr_ng.pl
Bareword "threads::joinable" not allowed while "strict subs" in use at acct_mgr_ng.pl line 117.
BEGIN not safe after errors--compilation aborted at acct_mgr_ng.pl line 541.

When threads is loaded, perl knows that threads::all (and friends) is a subroutine call, even without parentheses or &; since threads may not be loaded, just explicitly call it with parentheses: threads::all()

use statements are parsed at compile-time. You want to use require or Module::Load to pull in modules conditionally at run-time.
Something like this should work:
use Module::Load ();
if($Config{'useithreads'}) {
Module::Load::load("threads");
}

Related

What is the Lua "replacement" for the pre_exec command in Conky files?

I'm not great at programming, but I was trying to fiddle around with a conky_rc file I liked that I found that seemed pretty straight-forward.
As the title states, I have now learned that the previous command of pre_exec has been long removed and superseded by Lua.
Unfortunately, I cannot seem to find anything directly related to this other than https://github.com/brndnmtthws/conky/issues/62. The thread https://github.com/brndnmtthws/conky/issues/146 references it, and its "solution" states: Basically, there is no replacement and you should use Lua or use a very large interval and execi.
I have found a few more threads that all include the question as to why this function was discontinued, but with no actual answers. So, to reiterate mine, I have absolutely no knowledge of Lua (I've heard of it before, and I've now added a few websites to look at tomorrow since I have spent most of the evening trying to figure out this Conky thing), and I'll probably just give up and do the execi option (my computer can handle it but, I just think it's so horribly inefficient).
Is there an appropriate Lua option? If so, would someone please direct me to either the manual or wiki for it, or explain it? Or is the "proper" Lua solution this?
#Vincent-C It's not working for your script is because the function
ain't getting call. from the quick few tests I did, it seem
lua_startup_hook need the function to be in another file that is
loaded using lua_load, not really sure how the hook function thingy
all works cause I rather just directly use the config as lua since it
is lua.
Basically just call the io.popen stuff and concat it into conky.text
conky.text = [[ a lot of stuff... ${color green} ]];
o = io.popen('fortune -s | cowsay', 'r') conky.text = conky.text ..
o:read('*a')
The comment by asl97 on the first page you cited appears to provide an answer, but a bit of explanation would probably help.
asl97 provides the following general purpose Lua function to use as a substitute for $pre_exec, preceded by a require statement to make io available for use by the function:
require 'io'
function pre_exec(cmd)
local handle = io.popen(cmd)
local output = handle:read("*a")
handle:close()
return output
end
Adding this block of code to your conky configuration file will make the function available for use therein. For testing, I added it above the conky.config = { ... } section.
Calling the Lua pre_exec function will return a string containing the output of the command passed to it. The conky.text section from [[ to ]] is also a string, so it can then be conactenated to the string returned by pre_exec using the .. operator, as shown in the usage section provided by asl97.
In my test, I did the following silly bit, which worked as expected, to display "Hello World!" and the output of the date function with spacing above and below each at the top of my conky display:
conky.text = pre_exec("echo; echo Hello World!; echo; date; echo")..[[
-- lots of boring conky stuff --
]]
More serious commands can, of course, be used with pre_exec, as shown by asl97.
One thing that asl97 didn't explain was how to provide how to concatenate so that the pre_exec output is in the middle of the conky display rather than just the beginning. I tested and found that you can do it like the following:
conky.text = [[
-- some conky stuff --
]]..pre_exec("your_important_command")..[[
-- more conky stuff --
]]

Python3 - sanitizing user input passed to shell as parameter

What is the recommended method of sanitizing user_input_parameter passed to the shell like
subprocess.Popen(['sudo', 'rm -rf', user_input_parameter])
The command should accept all parameters but malicious activies like breaking out of the command should be mitigated.
Python's implementation of subprocess protects against shell injection, documentation says so:
17.5.2. Security Considerations
Unlike some other popen functions, this implementation will never
implicitly call a system shell. This means that all characters,
including shell metacharacters, can safely be passed to child
processes. If the shell is invoked explicitly, via shell=True, it is
the application’s responsibility to ensure that all whitespace and
metacharacters are quoted appropriately to avoid shell injection
vulnerabilities.
When using shell=True, the shlex.quote() function can be used to
properly escape whitespace and shell metacharacters in strings that
are going to be used to construct shell commands.
This will however NOT protect against a user passing a malicious input - in your case for example deleting something that was not intended to be deleted. I would not pass user input to the command directly like that - you should verify if whatever you want to be deleted is being deleted and not something completely different. That is however part of application's logic already - regarding shell injection (breaking out of the command) - that should be fine with subprocess.
I made this little example:
#!/usr/bin/env python3
import subprocess
user_input_parameter = '/; id'
subprocess.Popen(['ls', user_input_parameter])
Which outputs this when executed:
$ python3 asdf.py
ls: /; id: No such file or directory
$
To demonstrate subprocess passes the input as an argument to the parameter.
All of this is true only if shell=False (default as of writing this answer) for subprocess methods, otherwise you basically enable shell (bash, etc.) execution and allow for injection to happen if inputs are not properly sanitized.
Btw, you need to pass each parameter separately, so you would need to run it like this (but please don't do that):
subprocess.Popen(['sudo', 'rm', '-rf', user_input_parameter])

Variable argument list with different types in MetaTrader5

I have some mql5 code which I want to print debug messages if the DEBUG macro is set. I would like to use a different function (DebugPrint for that matter) for those debug messages. My first attempt was to create a regular function, but variable arguments don't seem to work. I then tried to use the precompiler to remove the DebugPrint-calls based on this answer, however the compiler's pre-processor doesn't seem to understand the variable argument list either. This is the code I tried:
#ifdef DEBUG
#define DebugPrint(...)
#else
#define DebugPrint(...) Print(__VA_ARGS__)
#endif
Any ideas on how to achieve what I'm trying to do?
My few cents on MQL4/5:
Preprocessor directives:
while the revised New-MQL4.56789 compiler has opened some new, more complex constructs for #define preprocessor directives syntax, I have almost always burnt my fingers when trying to use them in production code.
Variadic arguments:
MQL4/5 is a strong-typed, compiled language and as such does not provide means for variadic functions. With some recent syntax aids, coming from ( OOP ) Class-based function ( method ) call-interface overrides and maybe using some advanced abstractions from so called function-template-s, there are chances to create some sort of syntax-support for your #define-dependent behaviour.
Function Overloading,template-sandtypename-dependent actions:
Whereas these techniques have brought even more "New" compiler features into the MQL4/5 software domain, the additional levels of complexity do not justify the efforts, given the resulting principles are restricted from being usable in cases where their use is restricted from export, virtual or #import constructs.
So how to make this work?
Well, for the sake of the rapid & iterative development needs, one may resort to an "almost-variadic" PrintFormat( DEBUG_MASK, ..., ..., ... ); using a context-full (known) matching set of attributes against a static, context-specific #define-ed DEBUG_MASK. Nested construction of FormatString( MASK_A, par1, par2[, FormatString( MASK_B, par3, par4[, FormatString( ... )[, ... ] )[, ... ]) are left for one's own kind imagination.

How do I assure that a module is loaded only if the script is running on Windows?

I have a Perl script that needs to run on both Windows and Linux. The problem is I need to use a Perl module that only applies to Windows.
I have tried the below, but it still includes thie WindowsStuff package.
use strict;
if ($^O eq 'MSWin32' ){
use My::WindowsStuff;
}
use File::Basename;
use Getopt::Long;
...
...
Because use takes effect at compile time, it doesn't respect the ordinary flow control of the code being compiled.
In particular, putting a use inside the false branch of a conditional doesn't prevent it from being processed.
What you can do?
a) require import (run-time):
if( $^O eq 'MSWin32' ) {
require My::WindowsStuff;
My::WindowsStuff->import if My::WindowsStuff->can("import");
}
b) use if (compile-time):
use if $^O eq 'MSWin32', "My::WindowsStuff";

perl byte code generation with too many file.pl

How to make perl bytecode if sub is there in another file.pl so that I can get all perl script in to binary to give for usage but I am getting codedump warning.
Here is the example how I have done!
File: add.pl
require "util.pl";
$a = 1;
$b = 2;
$res = add($a,$b);
print $res;
File: util.pl
sub add()
{
my ($a,$b) = #_;
my $c = $a + $b;
return $c;
}
1; #to return true
Then when I run:
perlcc add.pl
./a.out
I get
Segmentation fault (core dumped)
I also tried
perlcc add.pl util.pl
but it says
/usr/bin/perlcc: using add.pl as input file, ignoring util.pl
Note:
If both are in single file
perlcc file.pl
and
./a.out
will work
I cannot answer for the actual compiler problem, but let me make a few notes.
<Edit> the more I look at this, the more I think that the problem is the namespacing of the add function. When they are in the same file, the function is declared in the main namespace. I think that would be true of the require-d file too, since there was not package declaration. Either way, these are still some good notes that I hope help. </Edit>
You really should use strict and warnings pragmas
You shouldn't use $a and $b, because they are semi-magical in Perl and should be avoided (yeah, thats a weird one)
Perl prototypes are not the same as most languages, and even then the empty prototype () on your add function is incorrect, best to leave it off
Those things said here is how I would format my files.
File: add.pl
use strict;
use warnings;
use MyUtils;
my $x = 1;
my $y = 2;
my $res = add($a,$b);
print $res;
File: MyUtils.pm
package MyUtils;
use strict;
use warnings
use parent 'Exporter';
our #EXPORT = ('add');
sub add
{
my ($x,$y) = #_;
my $c = $x + $y;
return $c;
}
1;
This uses the more modern module/package formalism for reusable libraries. The use directive contains a require directive, but does it at compile-time rather than run-time.
The Exporter module (and the #EXPORT variable) correctly import the function into the script's namespace (typically main).
Perhaps perlcc will like these changes better; but even if not, these are good practices to get used to.
perlcc was removed from Perl in version 5.10.0 (almost five years ago). The perldelta manual page has this to say:
perlcc, the byteloader and the supporting modules (B::C, B::CC,
B::Bytecode, etc.) are no longer distributed with the perl sources.
Those experimental tools have never worked reliably, and, due to the
lack of volunteers to keep them in line with the perl interpreter
developments, it was decided to remove them instead of shipping a
broken version of those.
Seeing that, I have to suggest that using perlcc with any version of Perl is probably a rather bad idea. It was an experimental feature that never really worked. You probably want to move away from using it.

Resources