Best linux questions in December 2010

How can I make VIM play typewriter sound when I write a letter?

14 votes

After a lot of writing in Q10 on Windows, I got used to the typewriter sound it makes every time you press a key. At least for me it feels great to have this sort of sound feedback.

On Linux on the other hand, I love writing it VIM, because of it's editing features. How could I add this functionality to VIM?

Simply said, I want to play a sound every time I press a key in the insert mode.

Alright, this kinda crazy, but it appears to work. First, grab yourself a typewriter sound in aiff format. Then put that typewriter sound in ~/.vim/support/my_typewriter_sound.aiff. Then add the following to your ~/.vimrc.

function! PlaySound()
  silent! exec '!afplay ~/.vim/support/my_typewriter_sound.aiff &'
endfunction
autocmd CursorMovedI * call PlaySound()

Note that the above function calls out to afplay, which I know works on a Mac and needs to be replaced with play on Linux. On Windows, I have no idea.

So you know what's happening above, we're first creating a function called PlaySound that shells out to afplay. We then setup an autocommand that gets fired anytime the cursor moves in insert mode. When it fires, it calls PlaySound.

Child processes die when killing parent if one of them is stopped with SIGSTOP

12 votes

My test code is

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main() {
  int c = fork();
  if (c == 0) while(1);
  c = fork();
  if (c == 0) while(1);
  c = fork();
  if (c == 0) while(1);
  c = fork();
  if (c == 0) while(1);
  while(1);
}

So I have one parent and 4 childs. When I kill the parent, childs are working fine with init as a parent. But if I stop (with SIGSTOP) one of the childs and then kill the parent, childs are killed too. Why this is so?

Apparently if a process in the process group is stopped, all processes are signalled with SIGHUP and then SIGCONT when the process group leader is terminated. The default handler for SIGHUP terminates the process. It is expected behaviour, as documented in e.g.

http://www.win.tue.nl/~aeb/linux/lk/lk-10.html

From the above link:

If termination of a process causes a process group to become orphaned, and some member is stopped, then all are sent first SIGHUP and then SIGCONT.

The idea is that perhaps the parent of the process group leader is a job control shell. (In the same session but a different process group.) As long as this parent is alive, it can handle the stopping and starting of members in the process group. When it dies, there may be nobody to continue stopped processes. Therefore, these stopped processes are sent SIGHUP, so that they die unless they catch or ignore it, and then SIGCONT to continue them.

EDIT:

BTW, strace is a wonderful tool for getting to the bottom of stuff like this. If you attach strace to one of the child processes you will see that SIGHUP is delivered only if one of then is stopped when the parent (i.e. the process group leader) dies.

You need to change the handler for SIGHUP using e.g. sigaction(2) if you want the children processes to survive.

Is there a standard alternative to Fiddler (Fiddler2) for Linux?

10 votes

I am aware this question has been asked before, but that was almost a year ago and I was wondering if maybe some thing new is available.

I would like to be able to have most of the functionality of Fiddler2 in Linux (I prefer Linux for my development environment). Listen to HTTP traffic, clone/edit requests, automatically decompress, filter/search, etc.

I use Charles on Mac, Linux, and Windows. It is commercial software.

Edit: ... and I see now this is the accepted answer in the previous question, so no. Nothing new!

Web-base IDE with shell / file management integration for *nix

9 votes

Hi,

is there anything like a web application (like in php) that exposes access to the files on the server it's installed on, shell access and integrated IDE?

I know it's not something secure, but for development purposes it would be useful when you have a *nix dev server you can't directly access (like, you're behind a proxy and can only navigate *:80).

I know of various administration tools a-la Webadmin or cPanel, but they lack any sort of web-based IDE to edit the files (as long as i know).

Maybe Mozilla Skywriter (ex Project Bespin) is similar to what I'm after, but I'm not sure about its current state (considering that they're in the process of rewriting it) and most of all i think it lacks server-side integration.

Any suggestion appreciated.

Have you tried ShiftEdit or CodeRun?

Both are web-based HTML/CSS/JS/PHP editor with some decent IDE features (snippets, syntax debugging). I believe both are SaaS, so no hosting it on your own machine.

You might also be interested in ECCO, which is open-source, so you can self-host it.

Save file as root after editing as non-root

8 votes

Ok so this happens to me all the time. There has to be a better solution. Let's say you do vim /etc/somefile.conf and then you do i but realize you are not sudo and you can't write. So then I lose my changes by doing :q then sudo !! and make my changes again. Is there a better way to do this?

Try

:w !sudo tee %

The w ! takes the entire file and pipes it into a shell command. The shell command is sudo tee which runs tee as superuser. % is replaced with the current file name.

How to disable socket creation for a Linux process, for sandboxing?

7 votes

I'm considering several options for sandboxing a Linux process. Using clone() with CLONE_NEWNET (etc.) is one of the options. CLONE_NEWNET ensures that the the sandboxed process cannot make or accept real network connections. But I'd like to disable sockets entirely for that process, even bind()ing to any port on 0.0.0.0, and binding to a Unix doman socket (even anonymous). I'd like to do this to prevent the process from using too much kernel resources by binding to thousands of ports. How do I do that?

In general, I'm interested in many sandboxing approaches (i.e. those provided by the Linux kernel and those enforced by ptrace()), but in this question I'm only interested in the socket creation aspect of the sandboxing approaches (so if you suggest a sandboxing approach, please also explain how to prevent socket creation with it), and I'm not interested in approaches which need kernel patching or which involve loading a kernel module which is not part of the Ubuntu Lucid default binary kernel package, or which would affect every process on the system.

ptrace seems to be the most obvious tool but aside from that…

util-linux[-ng] has a command unshare, which uses the kernel's clone/unshare interfaces. If you run the new process throughunshare -n (or clone(CLONE_NEWNET)), any network sockets it creates are in a different namespace. That doesn't solve the kernel resource issue but it does sandbox the process.

The Linux kernel also supports seccomp, a mode entered with prctl(PR_SET_SECCOMP, 1) which prevents the process (well, thread, really) from calling any syscalls other than read, write, exit, and sigreturn. It's a pretty effective sandbox but difficult to use with unmodified code.

You can define a SELinux domain which disallows socket/bind/etc. calls, and perform a dynamic transition into that type. This (obviously) requires a system with an actively enforcing SELinux policy. (Possibly similar things are possible with AppArmor and TOMOYO, but I'm not very familiar with any of them.)

What are my environment variables?

7 votes

I would like to find out my environment variables in bash. Are they stored somewhere?

I am not sure if thats what you want, but try printenv
This will show you all your environment variables.

About where they are stored
Linux: where are environment variables stored?

How to set Shell Environment Variables
http://www.codecoffee.com/tipsforlinux/articles/030.html

Happy readding :-)

Safe String Functions In Mac OS X and Linux

7 votes

Hello guys, are there are equivalent secure string functions in Mac OSX and Linux just like the ones in Windows (strcpy_s,strncpy_s..etc) ?

What about functions that convert between multi-byte and wide characters?

There are two strategies for safe string manipulation. The Linux/GNU C library maintainers refuse to add safe functions, arguing that you should keep the length of your strings at hand and use memcpy. MacOS X, OTOH, includes strlcpy and strlcat from BSD. snprintf and asprintf can be used on both platforms to much the same effect:

size_t strlcpy(char *d, char const *s, size_t n)
{
    return snprintf(d, n, "%s", s);
}

size_t strlcat(char *d, char const *s, size_t n)
{
    return snprintf(d, n, "%s%s", d, s);
}

Conversion between character encodings is most easily handled using the iconv interface.

Compile C++ for all linux distributions

6 votes

Hello,

How can i compile my C++ files to work on ALL linux distributions. The machine that i'll compile them on is Ubuntu 10.10

If i compile them on Ubuntu 10.10, will they work on other Distros like ubuntu, fedora, debian, non debian distros.. etc?

% gcc -o foo foo.c -static

the resulting binary should work on most distros, given that it runs on the same architecture (64bit, 32bit, arm, mips etc).

the main point is: since you do not know what can be found on the target systems in advance, you have to bundle everything you can into either the binary you are shipping or in some kind of "chrooted" environment where you deploy external libs as well (stuff that can't be linked statically) and then have some kind of a wrapper to use your deployed libs instead of the system libs.

How to know if a program ended its execution via a signal?

6 votes

Hello, I'm writing a program monitor as an assignment for an operating systems course (very basic though, like an introduction to it).

One of the things the monitor has to do is to show the termination code of the program it was monitoring if it ended by "natural causes" or the code of the signal responsible for its termination.

Right now I'm just waiting for the child to end its execution and then capturing its termination code. This is the related code snippet:

pid_t id = -1;
switch (id = fork()) {
    // Error when forking:
    case -1:
        error(-1, "Something went wrong when forking.");
        exit(-1);
    // Code for the child process:
    case 0:
        // Just launch the program we're asked to:
        execvp(argv[2], &argv[2]);
        // If reached here it wasn't possible to launch the process:
        error(1, "Process could not be launched.");
        exit(1);
    // Code for the parent process:
    default:
        // Just wait for the child to finish its execution:
        wait(&return_value);
}

error(2) is a logger function, just to simplify the code whenever an error arises.

Depending on how the process I have to show different statements:

Process ended: X

or

Process terminated with signal X.

Where X would be the termination code or the signal received. How could we know if the child process ended because of a signal?

From wait(2):

   WIFSIGNALED(status)
          returns true if the child process was terminated by a signal.
   WTERMSIG(status)
          returns  the  number  of the signal that caused the child process to terminate.

So you need to check WIFSIGNALED(return_value) and if it is true, check WTERMSIG(return_value).

looking for a stand-alone, in-memory data server with sequential access

5 votes

We need an in-memory data structure / DB server with following characteristics:

  1. stand-alone server: will run on the same machine as the clients, so any kind of IPC is ok
  2. sequential access: get next/previous key
  3. two keys (string) per record: kind of a bi-directional map, actually
  4. in-memory only: should have option for no persistence at all
  5. RAM disk/tmpfs solution is not desirable
  6. SQL/ODBC is an option, although not required
  7. commercial product ok, if the OEM license price is reasonable

So far we have considered the following options, but no satisfactory solution yet:

  • mysql: answers all requirements, but now answer yet as to how much an OEM license will cost
  • memcached, cassandra: no sequential access, according to online docs
  • Redis: seems as a nice tool, but again, I don't see get get nex/prev in the spec
  • Postgres: couldn't make it work well on Linux/ODBC

Seems that all nosql in-memory DBs provide only direct access by key, hash-table style. Have not checked Apache Derby yet.

We run on Linux, the client is in C++.

Will be glad to have your suggestions. Thanks!

EDIT: It seems that we will be pursuing the mysql option, we've got a reasonable price offer, and it will also be useful as our main (persistent) DB. Thanks for all answers, it is as usual difficult to select just one.

I'd suggest Kyoto Cabinet, it has an in memory function and sequential access.

edit: what's wrong with stl map?

How to align 3 files based on first column value

5 votes

I have 3 text files c.dat, n.dat, and h.dat The contents are similar, in this format

c.dat    n.dat    h.dat
1 0.ccc  3 1.nnn  1 2.hhh
2 0.ccc  4 1.nnn  2 2.hhh
4 0.ccc  5 1.nnn  5 2.hhh

Desired output:

1 0.ccc Inf 2.hhh
2 0.ccc Inf 2.hhh
3 Inf 1.nnn Inf
4 0.ccc 1.nnn Inf
5 Inf 1.nnn 2.hhh
6 Inf Inf Inf
7 ....

Each file has ~100 rows, but they don't always start from 1, and don't aren't always consecutive.

I need to align the 3 files by the first column, such that if the other files don't have it, it's filled in with something like NA, or NaN, or Inf... anything.

Thanks!

awk '
{
        if(FNR==1){f++}
        a[$1,f] = $2
        if($1 > max){max = $1}
}

END{
        for(j=1;j<=max;j++){
          printf("%d\t", j)
          for(i=1;i<=f;i++){
            if(!a[j,i]){printf("Inf\t")}
            else{printf("%s\t", a[j,i])}
          }
          printf("\n")
        }
}' ./c.dat ./n.dat ./h.dat

Output

$ ./awk.dat
1       0.ccc   Inf     2.hhh
2       0.ccc   Inf     2.hhh
3       Inf     1.nnn   Inf
4       0.ccc   1.nnn   Inf
5       Inf     1.nnn   2.hhh

I'm using tcp for very many small sends, should I turn off Nagles algorithm? (People also know this as TCP_NODELAY)

5 votes

I remade this post because my title choice was horrible, sorry about that. My new post can be found here: After sending a lot, my send() call causes my program to stall completely. How is this possible?

Thank you very much everyone. The problem was that the clients are actually bots and they never read from the connections. (Feels foolish)

TCP_NODELAY might help latency of small packets from sender to receiver, but the description you gave points into different direction. I can imagine the following:

  • Sending more data than receivers actually consume - this eventually overflows sender's buffer (SO_SNDBUF) and causes the server process to appear "stuck" in the send(2) system call. At this point the kernel waits for the other end to acknowledge some of the outstanding data, but the receiver does not expect it, so it does not recv(2).

There are probably other explanations, but it's hard to tell without seeing the code.