Re: The "Unix Philosophy 2020" document

2019-11-24 Thread Casper Ti. Vector
On Sun, Nov 24, 2019 at 05:13:15PM -0300, Guillermo wrote:
> Those are just two if statements 'sharing' a body for brevity. That
> deals with errors in the openat() and subsequent write() calls, for
> the file that controls cgroup membership. By displaying a message
> constructed in the same way in both cases, and then throwing an
> exception. *Shrug*

That particular piece of code
> if (0 > cgroup_procs_fd.get()) {
> procs_file_error: ...
> }
> if (0 > write(cgroup_procs_fd.get(), "0\n", 2)) goto procs_file_error;
seems equivalent to
> if (0 > cgroup_procs_fd.get() ||
> 0 > write(cgroup_procs_fd.get(), "0\n", 2)) {
> ...
> }

If the error handling branches that need reuse become more complex, the
following way can also be considered (cf. [1]):
> ...
> if (...) goto err;
> ...
> if (...) goto err;
> ...
> return;
> err:
> ...
> return;

Macros and/or helper functions (again cf. [1]; they can be factored into
a mini-library in nosh) can also be used to reduce boilerplate like
> const int error(errno);
> std::fprintf(stderr, ..., std::strerror(error));
> throw EXIT_FAILURE;
which can be easily observed after the attached patch is applied.

BTW, it seems that the value of errno is passed to std::strerror()
before anything can change the errno, which implies that `const int
error(errno);' can be left out and `errno' can be directly used as the
argument of std::strerror().

[1] .

-- 
My current OpenPGP key:
RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19)
7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C

--- move-to-control-group.cpp	2018-09-14 21:48:55.0 +0800
+++ move-to-control-group.new.cpp	2019-11-25 10:50:20.518459398 +0800
@@ -50,9 +50,8 @@
 	next_prog = arg0_of(args);
 
 	FileStar self_cgroup(open_my_control_group_info("/proc/self/cgroup"));
-	if (!self_cgroup) {
+	if (!self_cgroup && ENOENT != errno) {  // `ENOENT == error' is what we'll see on a BSD.
 		const int error(errno);
-		if (ENOENT == error) return;	// This is what we'll see on a BSD.
 		std::fprintf(stderr, "%s: FATAL: %s: %s\n", prog, "/proc/self/cgroup", std::strerror(error));
 		throw EXIT_FAILURE;
 	}
@@ -73,20 +72,16 @@
 
 	current = prefix + current;
 
-	if (0 > mkdirat(AT_FDCWD, current.c_str(), 0755)) {
+	if (0 > mkdirat(AT_FDCWD, current.c_str(), 0755) && EEXIST != error) {
 		const int error(errno);
-		if (EEXIST != error) {
-			std::fprintf(stderr, "%s: FATAL: %s: %s\n", prog, current.c_str(), std::strerror(error));
-			throw EXIT_FAILURE;
-		}
+		std::fprintf(stderr, "%s: FATAL: %s: %s\n", prog, current.c_str(), std::strerror(error));
+		throw EXIT_FAILURE;
 	}
 
 	const FileDescriptorOwner cgroup_procs_fd(open_appendexisting_at(AT_FDCWD, (current + "/cgroup.procs").c_str()));
-	if (0 > cgroup_procs_fd.get()) {
-procs_file_error:
+	if (0 > cgroup_procs_fd.get() || 0 > write(cgroup_procs_fd.get(), "0\n", 2)) {
 		const int error(errno);
 		std::fprintf(stderr, "%s: FATAL: %s%s: %s\n", prog, current.c_str(), "/cgroup.procs", std::strerror(error));
 		throw EXIT_FAILURE;
 	}
-	if (0 > write(cgroup_procs_fd.get(), "0\n", 2)) goto procs_file_error;
 }


Re: The "Unix Philosophy 2020" document

2019-11-24 Thread Guillermo
El dom., 17 nov. 2019 a las 4:28, Casper Ti. Vector escribió:
>
> A system proponent gave a remark about nosh's `move-to-control-group',
> which appears, to some degree, justified:
> 

Those are just two if statements 'sharing' a body for brevity. That
deals with errors in the openat() and subsequent write() calls, for
the file that controls cgroup membership. By displaying a message
constructed in the same way in both cases, and then throwing an
exception. *Shrug*

As I understand it, throwing the exception is necessary. Not only does
that transfer control directly to main(), destroying all objects with
automatic storage duration in its way, but also main() is written in
such a way that doing so makes the move-to-control-group process exit
with the code contained in the exception object, rather than chain
loading the next program. The error message could be optional, but I'm
sure human users appreciate that there is one :)

G.