-2

I am currently trying to get network interface names from Linux file "/proc/net/dev". I have two questions. First, I can get it by writing this code from 3rd line till the end of the file:

    char buffer[100], word[10];
    fgets(buffer, 100, fp);
    sscanf(buffer, "%s %*[:] %*s", word);

but the problem is I get the strings with a colon (lo: eth0: eth1:). How can I get them the way I can display on the screen.

The second question is why I get a segmentation fault on following code:

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

#define NETFILE "/proc/net/dev"

static char **interface_names;

int counting_lines()
{
    FILE *fp = fopen(NETFILE, "r");
    int i = 0;
    char buffer[200];

    while (fgets(buffer, sizeof(buffer), fp) != NULL)
    {
        i++;
    }
    fclose(fp);
    return i;
}

void do_malloc()
{
    int i;
    int lines = counting_lines() - 2;

    interface_names = (char **)malloc(lines * sizeof(char *));

    for (i = 0; i < lines; i++)
    {
        interface_names[i] = (char *)malloc(10 * sizeof(char));
    }
}

void free_malloc()
{
    int i;

    for (i = 0; i < (counting_lines() - 2); i++)
    {
        free(interface_names[i]);
    }
    free(interface_names);
}

void get_interface_names()
{
    FILE *fp = fopen(NETFILE, "r");
    int i = -2;
    char buffer[100];

    while (!feof(fp))
    {
        if (i < 0)
        {
            i++;
            continue;
        }
        else
        {
            fgets(buffer, 100, fp);
            sscanf(buffer, "%s %*[:] %*s", interface_names[i]);
            i++;
        }
    }
    fclose(fp);
}

int main()
{
    do_malloc();
    get_interface_names();
    printf("%s\n", interface_names[0]);
    printf("%d\n", counting_lines());
    free_malloc();
    return EXIT_SUCCESS;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612

1 Answers1

1

Your sscanf pattern is wrong. It should be:

        sscanf(buffer, " %9[^:] ", interface_names[i]);

The space at the beginning skips over any whitespace at the beginning of the line. Then it parses anything up to the next : and puts it into interface_names[i], with a maximum of 9 characters allowed (since interface_names[i] is 10 bytes).

Barmar
  • 741,623
  • 53
  • 500
  • 612