How can "plugins" loaded by libdl refer to symbols in the program which loaded them?

Imagine that you have an application with a plugin based architecture, where each plugin is a *.so file that is dynamically loaded with dlopen().

The main application can refer to symbols via dlsym(), and so it may call functions of the plugin. How can the plugin call functions of the main application?

I know that the main application could provide a struct full of function pointers, which the plugin could use to call into the application. Is there any easier way than that?

Edit: here’s a minimal working example to show what I mean:


#ifndef APP_H
#define APP_H
void app_utility(void);


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

#include "app.h"

void app_utility(void)

int main(int argc, char **argv)
    void *handle;
    void (*plugin_function)(void);
    if (argc < 2) {
        fprintf(stderr, "usage: ./app\n");

    handle = dlopen(argv[1], RTLD_NOW | RTLD_LOCAL);
    if (!handle) {
        fprintf(stderr, "error loading plugin: %s\n", dlerror());

    plugin_function = dlsym(handle, "doit");
    if (!plugin_function) {
        fprintf(stderr, "error loading symbol: %s\n", dlerror());


    return 0;


#include <stdio.h>

#include "app.h"

void doit(void)
    printf("did it!\n");

Example usage:

$ gcc -o app app.c -ldl
$ gcc -shared -o
$ ./app ./
error loading plugin: ./ undefined symbol: app_utility


There is a option you can pass to when you invoke it to create the executable for the main application: -rdynamic

$ gcc -rdynamic -o app app.c -ldl

The GCC documentation for -rdynamic:

Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program.

The ld manual page for --export-dynamic includes this paragraph:

If you use “dlopen” to load a dynamic object which needs to refer
back to the symbols defined by the program, rather than some
other dynamic object, then you will probably need to use this
option when linking the program itself.


Does all linux users are present on /etc/passwd?

There is one user “user1” which I cant find in /etc/passwd but I can execute cmds like

$touch abc
$chown user1 abc
$su user1

These command runs fine, but if I try to chown to some really nonexistent user these chown and su commands fail

I was wondering where is this user1 coming from?


While logged in with user1 (after su user1) execute:

getent passwd $USER

This fetches user passwd entries across different databases. All users are not necessarily system users – they can come from LDAP etc.
Check docs on getenv.

Also check your nsswitch.conf to see all sources used to obtain name-service information.

./path of file to execute not executing

I am trying to execute matlab from desktop path of file is


executing ./usr/local/MATLAB/R2017b/bin/matlab

also tried .//usr/local/MATLAB/R2017b/bin/matlab

and ./ /usr/local/MATLAB/R2017b/bin/matlab
how it works?


Just run /usr/local/MATLAB/R2017b/bin/matlab to access the binary via the full path otherwise you will run try to run it via the relative path: <CURRENT DIR>/usr/local/MATLAB/R2017b/bin/matlab if you put a . before.

You can also change the add /usr/local/MATLAB/R2017b/bin/ to your path variable in order to be able to execute the command matlab without having to specify its whole path each time.

Also change your ~/.bashrc file and add PATH=$PATH:/usr/local/MATLAB/R2017b/bin to be able to keep those change after a reboot and just run matlab

How can I do full outer join on multiple csv files (Linux or Scala)?

I have 620 csv files and they have different columns and data. For example:

word, count1
w1, 100
w2, 200

word, count2
w1, 12
w5, 22

//Similarly fileN.csv
word, countN
w7, 17
w2, 28

My expected output

word, count1, count2, countN
w1,    100,     12,    null
w2,    200 ,   null,    28  
w5,    null,    22,    null
w7,    null,   null,    17

I was able to do it in Scala for two files like this where df1 is file1.csv and df2 is file2.csv:

df1.join(df2, Seq("word"),"fullouter").show()

I need any solution, either in Scala or Linux command to do this.


Using Spark you can read all your files as a Dataframe and store it in a List[Dataframe]. After that you can apply reduce on that List for joining all the dataframes together. Following is the code using three Dataframes but you can extend and use same for all your files.

//create all three dummy DFs
val df1 = sc.parallelize(Seq(("w1", 100), ("w2", 200))).toDF("word", "count1")
val df2 = sc.parallelize(Seq(("w1", 12), ("w5", 22))).toDF("word", "count2")
val df3 = sc.parallelize(Seq(("w7", 17), ("w2", 28))).toDF("word", "count3")

//store all DFs in a list
val dfList: List[DataFrame] = List(df1, df2, df3)

//apply reduce function to join them together
val joinedDF = dfList.reduce((a, b) => a.join(b, Seq("word"), "fullouter"))
//|  w1|   100|    12|  null|
//|  w2|   200|  null|    28|
//|  w5|  null|    22|  null|
//|  w7|  null|  null|    17|

//To write to CSV file
  .option("header", "true")

This is how you can read all your files and store it in a List

//declare a ListBuffer to store all DFs
import scala.collection.mutable.ListBuffer
val dfList = ListBuffer[DataFrame]()

(1 to 620).foreach(x=>{
  val df: DataFrame =
    .option("header", "true")
    .load(BASE_PATH + s"file$x.csv")

  dfList += df

Why does the following C code skip the read() system call to execute the next write() system call?

My question is regarding Linux Systems Programming, specifically about the read and write APIs.

I am writing a program that replicates a shell. It takes a string argument and tokenizes it with a space delimiter. Depending on the command of the first token, it performs an operation using the remaining tokens as parameters. So far I have only implemented this for an ‘add’ command. The code runs in a loop until the user enters ‘n’ for ‘continue? [y/n]’. However, after the first iteration, my program skips the read() after the first write() call to enter command, and ends up at the ‘continue?’ write() call. Why does it skip the read() call immediately following the first write()?

int main (int argc, char *argv[]) {
int true=0;
while (true==0) {
    char buff1[]="Please enter your command\n";
    int count1= strlen(buff1);
    write (STDOUT_FILENO, buff1, count1);
    char buff2[100];
    int count2=read (STDIN_FILENO, buff2, 100);
    char *list[30]; //This creates an array of character pointers (strings)
    * Begin tokenization and entering tokens in list
    const char delim[]=" ";
    char *token;
    token=strtok(buff2, delim);
    const char newline[]="\n";
    int i=0;
    while (token!= NULL) {
        write (STDOUT_FILENO, newline, strlen(newline));
        write (STDOUT_FILENO, list[i], strlen(list[i]));
    * End tokenization

    * Begin Addition operation
    const char add[]="add";
    if (strcmp(list[0], add)==0) {
        int result=0;
        for (int j=1; j<i; j++) {
        char sum[50];
        int sumcount=sprintf(sum, "%d", result);
        write (STDOUT_FILENO, newline, strlen(newline));
        write (STDOUT_FILENO, sum, sumcount);
    * End Addition operation

    char *truefalse;
    char endmessage[]="Continue: [y/n]\n";
    write (STDOUT_FILENO, endmessage, strlen(endmessage));
    read (STDIN_FILENO, truefalse, 1);
    if (*truefalse=='n') {

return 0;

As this output image shows, in the second iteration, after asking me
to enter a command, the code skips to asking me to continue rather than
actually reading my command


Your program has undefined behavior.

You use a pointer that has not been initialized to point to anything valid.

The line

char *truefalse;

declares a pointer but it has not been initialized to point to anything valid. You go on to use it in the line

read (STDIN_FILENO, truefalse, 1);

Instead of

char *truefalse;
char endmessage[]="Continue: [y/n]\n";
write (STDOUT_FILENO, endmessage, strlen(endmessage));
read (STDIN_FILENO, truefalse, 1);


char truefalse; // Make it an object instead of a pointer.
char endmessage[]="Continue: [y/n]\n";
write (STDOUT_FILENO, endmessage, strlen(endmessage));
read (STDIN_FILENO, &truefalse, 1); // Use the address of the variable.


The reason your code does not wait for you to enter anything in the second iteration is that the newline character is still left in the input stream. The second call just reads the newline character.

You’ll need code to skip the rest of the line after reading the answer to the question.

The simplest way would be to use:

int c;
while ((c = fgetc(stdin)) != EOF && c != '\n');

Why the address of the pointer variable printed differently between two printf statements without any modification to the variable?

In below simple c test program two printf statements return different values. ( check last four printf statements).

int main ()
    char c, *cc;
    int i;
    long l;
    float f;
    c = 'Z';
    i = 15;
    l = 7777;
    f = 9999999312;
    cc = &c;
    printf("\nc = %c, cc= %u", *cc, cc);
    cc = &i;
    printf("\nc = %d, cc= %u", *cc, cc);
    cc = &l;
    printf("\nc = %ld, cc= %u", *( long* )cc, cc);
    printf("\nc = %ld, cc= %u", *cc, cc);
    cc = &f;
    printf("\nc = %f, cc= %u", *(float *)cc, cc);
    printf("\n cc= %u", cc);
    printf("\nc = %f, cc= %u", *cc, cc);
    printf("\nc = %f, cc= %u", *(float *)cc, cc);

    printf("\nc = %f, cc using pointer  = %p", *(float *)cc, cc);
    printf("\nc = %f, cc using pointer  =%p", *cc, cc);

    return 0;

output : –

c = Z, cc= 755585903
c = 15, cc= 755585904
c = 7777, cc= 755585912
c = 97, cc= 755585912
c = 9999998976.000000, cc= 755585908
cc= 755585908
c = 9999998976.000000, cc= 4294967288
c = 9999998976.000000, cc= 755585908
c = 9999998976.000000, cc using pointer  = 0x7ffc37f4ace4
c = 9999998976.000000, cc using pointer  =0xfffffff8

I am running it in eclipse ide and using Ubuntu Linux.

Why does it behave differently?


In several places you are using the wrong format specifier to printf. In particular, on this line:

printf("\nc = %f, cc= %u", *cc, cc);

The first parameter has type char, but you use %f which expects a double. Also, the second parameter has type char * but %u is expecting an unsigned int. Using the wrong format specifiers invokes undefined behavior.

That being said, here is what is most likely happening under the hood:

On most hosted implementations, floating point numbers are not pushed onto the stack the way integer types and pointers are, but are instead stored in a floating point register.

When you run the above printf command, both *cc and cc are pushed onto the stack because neither of them are floating point numbers. When printf then looks for the first parameter it sees %f, so it retrieves a value from a floating point register. Since you did actually pass a floating point value the prior time you called printf that value is still there, and that value happens to be the value you actually wanted to print, so that’s what gets printed.

Then when printf goes to print the next parameter, it sees %u in the format so the value is pulled from the stack. That value is *cc, which points to the first byte in the representation of f.

Assuming a float is a IEEE754 single precision floating point number, the value it contains is represented as 0xf8021550. The first byte of that is 0xf8. Since cc points to a char, which in your case appears to be signed, it is interpreted as a negative value. When passed to printf the value is promoted to type int, so the actual value passed in is 0xfffffff8, which is what you see being printed.

To reiterate however, the output you’re seeing is undefined behavior. The output could change if you build it on a different machine, use a different compiler, or just use a different optimization setting.

Provide password for running a script inside another script as different user

Imagine you run script as user A: sudo -u A ./
Inside that we have a line that calls another script with a different user B: sudo -u B ./ Now I get prompted to enter a password for user B. Is there any way to provide that password uppon call?

P.S. I know all the security breaches it can create. Please do not mention me that.


Yes you have option for that. But that password you have to provide at the time of executing the script or hard coded it in the script itself. Try with the below example:-

echo 'passwordofB' | sudo -u B -S ./

Also you can do it like:-

 sudo -u A ./ passwordofB #as a command line parameter

now inside

echo $1 | sudo -u B -S ./

You are executing another script sudo -u B ./ from script ./ right? So change that line with echo $1 | sudo -u B -S ./ and run your first script as sudo -u A ./ passwordofB where passwordofB is the password for user ‘B’