Budget astrophotograhy

We took a Nikon D5100 and Sigma 150-500 f5-6.3 to a designated dark spot in the Cotswolds. I’ve imaged Jupiter with this lens from South Manchester, at 5.1AU distance, so I figured I could get photos at least that good from a dark site, with Jupiter at 5AU distance.

Well here is Jupiter, with some motion blur due to my strong and stable tripod:

Just out of curiosity, I also tried to get some shots of Saturn. Saturn is ~10% smaller than Jupiter, and was also almost twice as far away (9AU distance), so I didn’t expect to get any detail – maybe an oval would be the best result I could manage at 500mm with glass optics?


(Click for viewer)
 

In the creative and poetic words of Donald Trump: “Wrong!” – Saturn’s rings are visibly distinct from the planet itself, although no moons were resolved in any of the photos I took.

That’s Saturn and rings at 9AU distance, on a D5100 body and with a Sigma 150-500mm lens, processed with RawTherapee.

Nice. Unfortunately 9AU is the closest Saturn gets so I’m unlikely to get a better photo with the budget equipment although I’ll take some with a 1metre f/5 Skywatcher when I get time. Jupiter’s closest approach is 4.5AU (10% closer than so I’ll also try Jupiter again with the telescope when it’s at closest approach – the Skywatcher should be able to resolve the atmospheric bands on Jupiter too.

C++: Generic locker class for thread-safe proxy-access to arbitrary objects

I created a template class which can be used to provide thread-safe access to methods and fields of some target object.
It provides a convenient double-smart-pointer proxy mechanism for accessing one method or field of the target, and a functor mechanism for executing multiple operations on the target within one lock.
Naturally with a RAII solution, the double-smart-pointer style provides no thread-safety for iterator/pointer-based access or any other kind of access which involves taking pointers/references to the target and accessing them outside the lock. For such use cases, wrap the entire operation in the functor style instead.

Source is below and also available on Github

#if 0
(
set -eu
declare -r tmp="$(mktemp)"
g++ -std=c++14 -Wall -Wextra -o "$tmp" "$0"
valgrind --quiet "$tmp"
)
exit 0
#endif
/* Run this file with bash to compile+execute it */
#include <mutex>
#include <iostream>
#include <type_traits>

/* Demo: double-smart pointer for automatic locking of arbitrary class */

template <typename T>
class ThreadSafe
{
	T t;
	mutable std::mutex mx;
	class Proxy
	{
		std::unique_lock<std::mutex> lock;
		T& t;
	public:
		explicit Proxy(std::mutex& mx, T& t) : lock(mx), t(t) { std::cout << "  (lock)" << std::endl; }
		Proxy(Proxy&& src) : lock(std::move(src.lock)), t(src.t) { }
		~Proxy() { std::cout << "  (unlock)" << std::endl; }
		T *operator -> () { return &t; }
	};
public:
	template <typename ...Args>
	explicit ThreadSafe(Args&&... args) : t(std::forward<Args>(args)...) { }
	Proxy operator -> () { return Proxy(mx, t); }
	template <typename Func, typename R = typename std::enable_if<!std::is_void<typename std::result_of<Func(T&)>::type>::value>::type>
	auto operator () (const Func& func) {
		std::lock_guard<std::mutex> lock(mx);
		return func(t);
	}
	template <typename Func, typename R = typename std::enable_if<std::is_void<typename std::result_of<Func(T&)>::type>::value>::type>
	void operator () (const Func& func) {
		func( * operator -> () . operator -> () );
	}
};

int main(int argc, char *argv[])
{
	(void) argc;
	(void) argv;
	/* Initialise s as a thread-safe wrapper around a std::string */
	ThreadSafe<std::string> s("potato");
	/* For doing one operation, the pointer proxy style is convenient */
	s->append("es are awesome");
	/* Function style: Passed function is executed within lock and may do multiple operations */
	s([] (auto& str) { str += "!"; });
	/* Not thread safe, as our lock object expires before the pointer is used.  Use the function style in place of this: */
	std::cout << s->c_str() << std::endl;
	return 0;
}

Why doesn’t “sudo echo value > target” work, and why pipe into “tee”?

Quick one here for beginners, since I’ve been asked this question quite a bit lately.

Problem and reason for it

When you type “sudo echo value > /sys/target” into a POSIX shell, the interpreter parses the command and comes up with something like this:

Program: sudo
Parameters: echo value
Input: STDIN
Output: /sys/target
Error: STDERR

Note that “sudo” is not a shell built-in command, it is a separate program which is not even installed on many Linux systems. When “sudo” is executed with those arguments, it opens a root shell and in that shell runs “echo value”. Whether “echo” is a shell built-in, or a separate binary (e.g. /bin/echo) the result should be the same: “value” is written to STDOUT.

The STDOUT for sudo however is not the console since sudo was run with the redirection to /sys/target. This leads us onto the reason why your command doesn’t work.

In order to execute your original command, a few system calls are involved:

  • Fork: The shell process fork into two processes
  • Open: The child process opens /sys/target for writing
  • Dup2: The child process maps the opened file as the STDOUT descriptor (replacing the previous file assigned to that descriptor)
  • Exec: The child process calls exec to replace itself with the desired program (sudo)

Note that this all occurs in your current security context, since “sudo” is not launched yet (the “exec” call launches “sudo”). So as a result, the “open” system call will fail, since your user account does not have the required permissions for opening the target file for writing. The “echo” and “sudo” do not fail because they aren’t even started.

Solutions

The solution to this is to do the output redirection from within the security context that “sudo” gives you. There are various ways to achieve this:

tee

Tee duplicates its input stream to multiple outputs (hence the name, “T”). Play with the following examples:

echo Hello | tee
echo Hello | tee /dev/stdout
echo Hello | tee /dev/stdout /dev/stderr
echo Hello | tee /dev/stdout /dev/stdout /dev/stdout

This is commonly used for redirecting from programs run with sudo:

echo value | sudo tee /sys/target

The “echo” program does not need to be run with sudo as just writes its parameters to STDOUT. “tee” is run with sudo as it needs to open the target file for writing. Note that since “tee” also copies the input data to its output, you will see your value written to the terminal when using this method.

Nested shell

Another method is to have “sudo” start a shell and redirect from within that shell:

sudo sh -c 'echo value > /sys/target'

If using single-quotes to wrap the command, this will prevent environment variables from your interactive shell from getting expanded into the command. Instead, expansion takes place in the root shell. This may be beneficial in some cases.

sudoers

The previous methods use sudo, which will typically ask for a password. If you want to permit certain operations to be run without requiring manual password entry (e.g. for scripting or for hoykeys), you can put the commands into scripts, chown the scripts so they’re owned by root, then edit the “sudoers” file appropriately.

setuid

You can also replace the scripts with C programs that call setuid to acquire root. After compiling, you must chown the programs to root and set the setuid bit on them so that they can acquire root automatically.

This method requires care since you’re allowing any user to run certain root-only operations. Be careful of what commands you permit to be run like this, take care to avoid buffer overruns/underruns, and compile in ultra-strict mode (-Wall -Wextra -pedantic -Werror -fstack-protector).