Category Archives: Linux

Go To Statement Considered Harmful (discussed)

Talking with other developers about control-flow patterns, after a while someone will cite Edgar Dijkstra’s paper

“Go To Statement Considered Harmful” Communications of the ACM 11, 3 (March 1968), pages 147-148

Usually those developers argue, that go to statements should be abolished completely.

Just, it is important to note, that this paper is about loop-control-structures, comparing the expressiveness of recursive function calls, while/repeat-statements and goto-statements with each other (preferred pattern mentioned first).

And Dijkstra does not oppose the usage of go to statements in general, but mentioning a use case for go to statements:

“The remark about the undesirability of the go to statement is far from new. I remember having read the explicit recommendation to restrict the use of the go to statement to alarm exits, but I have not been able to trace it; presumably, it has been made by C.A.R. Hoare.”

My interpretation of this statement is, that go to statements can be tolerated for so called “alarm exits” as being used widely in C-code of OS-Kernels and embedded systems.

An “alarm exit” may look like this, realizing a single exit point for the success case and a single one for the error case, instead of spreading multiple exit-points all over the function.

/**  foo reading a file and returns with SUCCESS, otherwise with ERROR
*/
int foo(const char* filename) {
int fd = INVALID_FD;
if (filename==INVALID_STRING) {
goto alarm_exit;
}
fd = open_file(filename);
if (fd == INVALID_FD) {
goto alarm_exit;
}
/* do something, release resource and exit with success */
close_file(fd);
return SUCCESS_CASE;

alarm_exit:
/* release resources if allocated */
if (fd!=INVALID_FD) close_file(fd);
return ERROR_CASE;
}

So, next time having a discussion with fundamental developers, abolishing all occurances of go to statements (even for the “alarm exits” use case), I will be happy to cite Dijkstra and Hoare ūüėČ

Eclipse – CDK – build – run as super user

If you develop your native C/C++ application with Eclipse CDK and the need to execute the newly build  application with permissions to access raw socket API, such as a tun-interface, I suggest to use Linux-capabilities. (Executing the newly build application as root/super user, can become very complex.)  The Linux-capabilities allow you to execute you app with regular user permissions, but being capable to access certain privileged interfaces of Linux.

I assume that your build environment builds the binary /home/myuser/workspace/proj/bin/myapp

## invoke command in terminal with root permissions
sudo setcap cap_net_admin,cap_net_raw=eip /home/myuser/workspace/proj/bin/myapp

Next you have got to add the following lines to /etc/security/capability.conf to grant these privileges to the developer/user myuser.

## add to file /etc/security/capability.conf
cap_net_admin myuser
cap_net_raw   myuser

If your application needs read/write access to raw network devices such as  /dev/net/tun, grant these privileges by adding the following line to the file /etc/udev/rules.d/50-udev.rules (assuming myuser is member of group admin)

## file /etc/udev/rules.d/50-udev.rules
KERNEL==”tun”, ¬†¬† ¬†NAME=”net/%k”, ¬†¬† ¬†GROUP=”users”, MODE=”0660″, OPTIONS+=”ignore_remove”

These take effect on next reboot. In the meantime do:
sudo chown root.admin /dev/net/tun
sudo chmod g+w /dev/net/tun

Now your application has the required permissions to execute privileged network operations. Now you have got to integrate the setcap invocation into the Makefile build process. Add the following line to your make-rule:

## Makefile rule
myapp:  $(APPLIBS) main.o
     $(CC) $(CFLAGS) $(LDFLAGS)  -o myapp main.o $(APPLIBS)
     sudo setcap cap_net_admin,cap_net_raw=eip /home/myuser/workspace/proj/bin/myapp

To avoid that sudo request the password, we add the following line to the very end of the file /etc/sudoers, replace myuser by the user-name of the developer.

## Add as last line of config file /etc/sudoers
myuser ALL = (ALL) NOPASSWD: /sbin/setcap, (ALL) NOPASSWD: /sbin/ifconfig

You will notice that we grant access as well to /sbin/ifconfig. This will allow our application to invoke ifconfig commands from within application to create the required network interfaces.

Finally very that the capabilities are configured for the freshly built binary. And you should see the capabilities are the one you set before.

## Execute in console:
sudo getcap myapp

Now you are done. You should be able to execute your application with normal user permissions from within Eclipse, and invoke privileged network operations.