J. Magalhães Cruz

Unix/Linux Classroom Tips/Answers to Frequent Problems

Base note: most if not all of the problems and tips/solutions presented are not original! This small compilation just aims to be of help to my students at FEUP.

Label/keywords Problem Solution Comment
./prog Tired of typing ./prog, instead of just prog, to run your program in the current working directory? Just add
export PATH=$PATH:.
in a single line near the end of one of the files: ~/.profile or ~/.bash_profile.
[~ means your home directory!]
This applies to (ba)sh. For (t)csh look elsewhere. (See why I prefer BASH in sh-vs-csh.html.)
Note1: the dot should be put last in the "export" line to defeat Trojan Horse attacks!
Note2: this practice is no-way recommended by Garfinkel & Spafford, because it could be used by Trojan Horses waiting for misspelled commands!
perror Want an easy way to find out why your syscall failed in a C program? Just add
perror ("appropriate label");
in your block of error condition detection.
Example:
  • code:
    • if ((fd = open (argv[1], O_RDONLY)) < 0) {
      perror("open");
      exit(1); }
  • on error, stderr will show (e.g.):
    • open: No such file or directory
setbuf While debugging C code with printf()s, want to be sure what was the last message printed to stdout before a crash ("Segmentation fault")? Just add
setbuf (stdout, NULL);
right at the beginning of main().
For performance reasons, remove the setbuf() after debugging.

Alternatives to this tip would be, for all calls to printf(...),

  • append to them fflush(stdout);
  • replace them with fprintf(stderr,...)

Make your choice!

"mode", file creation What’s the good of mode parameter (permission bits) in
open(pathname, flags, mode_t mode)
?
It is practically useless, and very misleading, as whatever is put there is bitwise ANDed with ~umask!
If you want to assure a specific permission mode for your new file, choose one:
  • after open(), do
    chmod(.., mode) or fchmod(.., mode)
  • mode_t old = umask(0777);
    open(.., .., mode);
    umask(old);
I fail to understand the "protection" achieved with the bitwise ANDing of mode with ~umask!
CTRL+C, process tree When CTRL+C is pressed do all processes in tree receive it? Yes, because keyboard driver sends SIGINT to foreground process group.
If you want to reproduce this behavior with kill command, do:
sh$ kill -SIGINT -pid
where pid referes to the root process of tree.
This is a simplification, although essentially correct.
Be sure to understand the meaning of "process tree", "foreground", "process group"...
parent, child, fork() Do really a "parent" process produces a "child", different, process by calling fork()? Parent/child processes is the nomenclature historically used in Unix; but it is unfortunate as it can be misleading, specially while programming.
More accurately, by calling fork() an original process gives rise to a clone (duplicate, replica) process. This is right after fork(); then if follows its own path and might become completely different (i.e. by calling exec...()).
The new process has a new identity (pid) and a few other differences; but it has the same code as the original and, initially, almost the same state (memory buffers, etc.).
All in all, the differences and similarities of the new process compared with the initial process are more compatible with the "clone" term, than with "child".
[Linux also has a specific syscall clone(), that is not an alias for fork().]
wait(), process tree Want to wait for all descendants of original process? You must include wait() at the end of the code of every process that called fork().
This is because in Unix a process can only wait for its direct children (not for its "grandchildren" and other descendants).
The man of wait/waitpid, although correct, is misleading:
first argument of waitpid() can be 0 or negative, «meaning wait for any child process...», but this only applies to direct children, not descendants!


2020