Sunday, November 18, 2012

Colorful Man Pages

    Manual pages are the most important documentation sources for developers. They are not useful only for linux commands but also for c/c++ functions and structures ever for kernel source codes'. In almost every linux distribution, pager is linked to "less" by default so that when an application needs to show output page to page on terminal, "less" is used. However "less" does not give a colorful output.

    If you want to see pages colorful which makes more readable, you can use "most" for that. Link your "pager" to the "most" instead of "less".

   Check your current pager:

        kays@debian:~$ update-alternatives --display pager
        pager - auto mode
          link currently points to /bin/less
        /bin/less - priority 77
          slave pager.1.gz: /usr/share/man/man1/less.1.gz
        /bin/more - priority 50
          slave pager.1.gz: /usr/share/man/man1/more.1.gz
        /usr/bin/pg - priority 10
          slave pager.1.gz: /usr/share/man/man1/pg.1.gz
        /usr/bin/w3m - priority 25
          slave pager.1.gz: /usr/share/man/man1/w3m.1.gz
        Current 'best' version is '/bin/less'.

   "less" is current pager. Install "most" package and make it your default pager as below:

        kays@debian:~$ sudo aptitude install most
        kays@debian:~$ sudo update-alternatives --install /usr/bin/pager pager /usr/bin/most 99

   You can use "--config" options as below by doing interactively:

        kays@debian:~$ sudo update-alternatives --config pager

   Now test your pager. Below is "socket" function manual page.

man socket

Friday, October 26, 2012

Get Rid Of MACRO Complexity When Tracing API Sources

     In C/C++ projects sometimes there are too many definitions and macro used. This is usually done to  add a layer between library sources and user implementation. Sometimes it is used to use template approach in C sources by "ifdef" and other similar preprocessors as below.

        /* unsigned integer multiplication in mul_ui.c */

        #define OPERATION_mul_ui
        #include "mul_i.h"

        /* signed integer multiplication in mul_si.h */

        #define OPERATION_mul_si
        #include "mul_i.h"

        /* mul_i.h */

        #ifdef OPERATION_mul_si
        #define FUNCTION               mpz_mul_si
        #define MULTIPLICAND_ABS(x)    ((unsigned long) ABS(x))

        #ifdef OPERATION_mul_ui
        #define FUNCTION               mpz_mul_ui
        #define MULTIPLICAND_UNSIGNED  unsigned
        #define MULTIPLICAND_ABS(x)    x
        #ifndef FUNCTION
        Error, error, unrecognised OPERATION

        void FUNCTION (mpz_ptr prod, mpz_srcptr mult,
                                MULTIPLICAND_UNSIGNED long int small_mult)
              /* ..... */

    At that time it is difficult to trace API sources and generally we lose our-self in definitions. Nowadays I use MPIR library which is common library for big numbers arithmetic and calculations. I need to trace API functions source codes and use functions implementations directly as inline into my own source codes in order to remove libraries function call costs. However there are plenty of definitions for types, functions, constants etc. As you know when compiler run, preprocessor is called at first and when processor finished its job then compiler starts to compile sources.

    In order to cope with that MACRO definitions complexity we can run gcc and tell him just run preprocessor and then exit without compiling sources. With "-E" parameter gcc does exactly what we need:

         gcc -E main.c > main_proprocessed.c

Friday, March 2, 2012

Redirecting Output of already Running Process II

     We can redirect standard output of a running process with gdb. However, in this method application is stopped by gdb and continue again. In fact, we can redirect standard output to anywhere/any file without stopping process with
some extra code. At below, we will explain how to define signals to control redirecting operation.

     POSIX lets user to define their signals. You should use "SIGUSR1" to define your signal(man 7 signal). We define two new signals, add lines below to your source:

         /* user define signals */
         #define SIG_DIRECT_STDOUT_TO_FILE (SIGUSR1+51)
         #define SIG_REDIRECT_STDOUT (SIGUSR1+52)

     We should define new file where standard outputs will be redirected to it. Of course, we can get this file name as parameter, read from environment etc.

         #define CASE_LOG_FILE "/tmp/caselog.txt"

     We want to redirect output when first signal received and reassign original output file to original file. For that purpose we should get original output file info before redirection.

         #define STDOUT_FILE_SIZE 256
         static char stdoutFilePath[STDOUT_FILE_SIZE];

     We should define our signal handler which responsible with redirection:

         /* Function for signal directing stdout to case log file */
         static void appSigDirect(int sig)
             fprintf(stderr, "SIG_DIRECT_STDOUT_TO_FILE entered, redirecting stdout to CASE_LOG_FILE!");
             freopen(CASE_LOG_FILE, "w", stdout);

         /* Function for signal redirecting stdout to original file */
         static void appSigRedirect(int sig)
             fprintf(stderr, "SIG_REDIRECT_STDOUT entered, redirecting stdout to original file: %s", stdoutFilePath);
             freopen(stdoutFilePath, "a", stdout);

     In main function we should assign original output file to stdoutFilePath[] and assign handler to appropriate signals.

         /* get initial stdout direct file path */
         readlink("/proc/self/fd/1", stdoutFilePath, STDOUT_FILE_SIZE);

         if (signal(SIG_DIRECT_STDOUT_TO_FILE, appSigDirect) == SIG_ERR)
             return -1;

         if (signal(SIG_REDIRECT_STDOUT, appSigRedirect) == SIG_ERR)
             return -1;

     Compile your code and run as you wish. For example if you run your application as below and your application process id is "$APP_PID", you should see "/proc/$APP_PID/fd/1" linked to "/tmp/mylog.txt":

         myapp > /tmp/mylog.txt &

     Now you can tail "/tmp/mylog.txt" file to see outputs come to that file. When you want to redirect your logs to "/tmp/caselog.txt",
send SIG_DIRECT_STDOUT_TO_FILE signal to your application. Since SIGUSR1 is defined 10 in linux, if you are using linux our signal will be 61.

         kill -61 $APP_PID

     At that point your application will update outputfile to "/tmp/caselog.txt" (check "/proc/$APP_PID/fd/1") and output logs will be written to caselog.txt instead of mylog.txt file.

     When you want to reassing mylog.txt file as output file, you can use SIG_REDIRECT_STDOUT signal which number is 62 in linux.

         kill -62 $APP_PID

Monday, February 27, 2012

Redirecting Output of already Running Process I

Every process has opened stdin, stdout and stderr files by default. Those files are opened when process is created. If standard files redirected to any file(devices are also file type in linux) you can check it on "/proc/$PID/fd/" directory where $PID is process id. Sometimes we may need to redirect output to another file. In that case we can do this with gdb. On the other hand, If you need this for your own application you can add redirecting standard files as a feature with a small code.
We can test gdb method with tail command. Open /var/log/messages with tail command and send output to /dev/null device.

      root@work:~# tail -f /var/log/messages > /dev/null &
      [1] 32312

We have a background process with pid "32287" and standard output have been redirected to /dev/null device. 

       root@work:~# ls -l /proc/32312/fd/1
       l-wx------ 1 root root 64 Feb 27 18:23 /proc/32312/fd/1 -> /dev/null

After sometimes we want to write message logs to another file. We will use gdb to change stdout file. First we attach gdb to our process with pid:

       gdb -p 32312

In gdb command line, we will close stdout file which fd is "1" and then we will create our new file and it will be smallest suitable file descriptor which means "1". Then we will need to detach and quit gdb.

       (gdb) p close(1)
       $1 = 0
       (gdb) p creat("/tmp/mylog.txt", 0600)
       $2 = 1
       (gdb) detach
       Detaching from program: /usr/bin/tail, process 32312
       (gdb) q

Let's check redirected output file of our process again and see the our new file:
       root@work:~# ls -l /proc/32312/fd/1
       l-wx------ 1 root root 64 Feb 27 18:23 /proc/32312/fd/1 -> /tmp/mylog.txt