GoonerZaid
GoonerZaid

Reputation: 11

Is there a way to command during runtime to not to call a particular function (to comment it out) in C (Linux)?

I want to specify during run-time to ignore a function call for a function (which is of course defined) inside my executable. Please suggest some methodology for doing the same in C language on Linux.

Upvotes: 0

Views: 54

Answers (2)

deamentiaemundi
deamentiaemundi

Reputation: 5525

You cannot ignore function calls at runtime, you either call the function or you don't.

But let's assume for the sake of this answer that there exists a condition under which the function gets called and at least another condition under which the function is not called.

You can tell the program these conditions in several ways, for example per command-line, change of environment/file, and probably a long list more. For simplicity let's use the command-line and give the conditions in form of a argument to the executable. Additionally, because it is simple and short, use a signal.

File optional_functions.c

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

#include <dlfcn.h>

static void a(void)
{
  puts("Function \"a\" called");
}

static void b(void)
{
  puts("Function \"b\" called");
}

static void c(void)
{
  puts("Function \"c\" called (by signal SIGINT)");
}

#include<signal.h>
#include<unistd.h>

static void signal_handler(int signal_number)
{
  if (signal_number == SIGINT) {
    c();
    exit(EXIT_SUCCESS);
  }
}


int main(int argc, char **argv)
{
  void *dynlib;
  void (*function_d) (void);
  char *dynlib_error;

  if (argc == 2) {
    if (argv[1][0] == 'a') {
      a();
    } else if (argv[1][0] == 'b') {
      b();
    } else if (argv[1][0] == 'd') {
      puts("External function \"d\" wanted, loading library");
      dynlib = dlopen("libfunctiond.so", RTLD_LAZY);
      if (dynlib == NULL) {
        fprintf(stderr, "Failed loading lib: %s\n", dlerror());
        exit(EXIT_FAILURE);
      }
      *(void **) (&function_d) = dlsym(dynlib, "d");
      dynlib_error = dlerror();
      if (dynlib_error != NULL) {
        fprintf(stderr, "Failed calling function \"d\" fom lib: %s\n",
                dynlib_error);
        exit(EXIT_FAILURE);
      }
      (*function_d) ();

    } else {
      fprintf(stderr, "A function named \"%c\" does not exist, bailing out\n",
              argv[1][0]);
      exit(EXIT_FAILURE);
    }
  } else {
    if (signal(SIGINT, signal_handler) == SIG_ERR) {
      fprintf(stderr, "signal catching failed, bailing out\n");
      exit(EXIT_FAILURE);
    }
    sleep(5);
    puts("Signal catching timed out, assuming no function wanted in the first place.");
  }
  exit(EXIT_SUCCESS);
}

File functiond.h

#ifndef FUNCTIOND_H
#define FUNCTIOND_H
void d(void);
#endif

File functiond.c

#include <stdio.h>
#include "functiond.h"
void d(void)
{
  puts("Function \"d\" called and says hello from the library");
}

Compile as

clang -Weverything -fPIC  -c functiond.c
clang -shared -Wl,-soname,libfunctiond.so.1 -o libfunctiond.so.1.0   functiond.o
ln -sf libfunctiond.so.1.0 libfunctiond.so.1
ln -sf libfunctiond.so.1 libfunctiond.so
clang -Weverything -o optional_functions optional_functions.c example.c -ldl

Run it

$ ./optional_functions # waiting 5 seconds
Signal catching timed out, assuming no function wanted in the first place.
$ ./optional_functions # press CTRL+c in less than 5 seonds
^CFunction "c" called (by signal SIGINT)
$ ./optional_functions 1
A function named "1" does not exist, bailing out.
$ ./optional_functions a
Function "a" called
$ ./optional_functions b
Function "b" called
$ ./optional_functions d
External function "d" wanted, loading library
Failed loading lib: libfunctiond.so: cannot open shared object file: No such file or directory

That was expected. Either give dlopen() the complete path to the library or let the environment variable LD_LIBRARY_PATH do the job:

$ LD_LIBRARY_PATH=. ./optional_functions d
External function "d" wanted, loading library
Function "d" called and says hello from the library

It is not the proper way to make, install and and use dynamic libraries, of course, but again: for the sake of simplicity…

Upvotes: 0

Syed Waris
Syed Waris

Reputation: 1074

Probably the best you can do is something like this:

// Filename mycode.c

int main()
{
  // ...
  #ifndef SOME_MACRO
  someFUnction();
  #endif

  //...

}


int someFUnction()
{

 // does something

}

To exclude the function call in main, you need to compile with

gcc -DSOME_MACRO mycode.c

If you will compile simply as

gcc mycode.c

then the function call will be enabled.

Upvotes: 1

Related Questions