Question

Je veux que mon programme toujours connaître tous les points de montage. Après un rapide Google j'ai trouvé que getmntent () et peut me dire ce qui est monté. Je me rends compte que je pouvais le faire à chaque fois que je devais savoir ce qui a été monté, mais est-il un moyen de reconnaître quand quelque chose que je n'ai pas monté se / démonté afin de continuer à lire le fichier? Est-ce que fait dBus?

Les conseils seraient utiles. Je suis en train de commencer la programmation (j'ai pris un cours sur C en 2002, quand j'étais au collège.) Et a trouvé une fonctionnalité que je veux mettre en œuvre un programme open source.

Était-ce utile?

La solution

D'après la mention de getmntent(), je vais vous deviner avez affaire à Linux (autres systèmes Unix comprennent aussi, mais ils sont beaucoup moins fréquent de nos jours ...). Si tel est le cas, man inotify devrait vous aider à démarrer.

Autres conseils

Si vous codez pour Linux (ou utilisez des librairies GNOME tout de même), GIO de GNOME offre une bonne API pour cela. Voici un moniteur d'entraînement trivial je l'ai écrit en C qui utilise GTK et GIO:

#include <gio/gio.h>
#include <gtk/gtk.h>
#include <string.h>

typedef struct {
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *scrolled_window;
    GtkWidget *view;
    GtkWidget *button;

    GtkListStore *store;
    GVolumeMonitor *monitor;
} Context[1];

enum {
    COL_DRIVE,
    COL_ICON,
    COL_NAME,
    NUM_COLS
};

static int find_drive(GtkTreeModel *model, GDrive *drive, GtkTreeIter *iter)
{
    gboolean valid;

    valid = gtk_tree_model_get_iter_first(model, iter);
    while (valid) {
        GDrive *cur;
        gtk_tree_model_get(model, iter, COL_DRIVE, &cur, -1);

        if (cur == drive)
            return 1;

        valid = gtk_tree_model_iter_next(model, iter);
    }

    return 0;
}

static void set_drive_iter(Context ctx, GDrive *drive, GtkTreeIter *iter)
{
    GIcon *icon = g_drive_get_icon(drive);
    gchar *name = g_drive_get_name(drive);

    gtk_list_store_set(ctx->store, iter,
        COL_DRIVE, drive,
        COL_ICON, icon,
        COL_NAME, name,
        -1);

    g_free(name);
}

static void add_drive(Context ctx, GDrive *drive)
{
    GtkTreeIter iter;
    gtk_list_store_append(ctx->store, &iter);
    set_drive_iter(ctx, drive, &iter);
}

static void refresh_drive_list(Context ctx)
{
    GList *drives, *l;
    drives = g_volume_monitor_get_connected_drives(ctx->monitor);

    gtk_list_store_clear(ctx->store);

    for (l = drives; l; l = l->next)
        add_drive(ctx, l->data);
}

static void update_drive(Context ctx, GDrive *drive)
{
    GtkTreeModel *model = GTK_TREE_MODEL(ctx->store);
    GtkTreeIter iter;

    if (find_drive(model, drive, &iter))
        set_drive_iter(ctx, drive, &iter);
    else
        refresh_drive_list(ctx); //Shouldn't happen
}

static void remove_drive(Context ctx, GDrive *drive)
{
    GtkTreeModel *model = GTK_TREE_MODEL(ctx->store);
    GtkTreeIter iter;

    if (find_drive(model, drive, &iter))
        gtk_list_store_remove(ctx->store, &iter);
    else
        refresh_drive_list(ctx); //Shouldn't happen
}

static void init_drive_list(Context ctx)
{
    ctx->store = gtk_list_store_new(3, G_TYPE_POINTER, G_TYPE_ICON, G_TYPE_STRING);
    refresh_drive_list(ctx);
}

static void init_drive_view(Context ctx)
{
    GtkTreeViewColumn *column;
    GtkCellRenderer *renderer;

    ctx->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ctx->store));
    g_object_set(ctx->view,
        "headers-visible", FALSE,
        NULL);

    renderer = gtk_cell_renderer_pixbuf_new();
    g_object_set(renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
    column = gtk_tree_view_column_new_with_attributes("Icon", renderer, "gicon", COL_ICON, NULL);
    gtk_tree_view_column_set_resizable(column, TRUE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(ctx->view), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", COL_NAME, NULL);
    gtk_tree_view_column_set_resizable(column, TRUE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(ctx->view), column);
}

static void print_drive_info(GDrive *drive)
{
    GIcon *icon;
    gchar *name, *icon_string;

    name = g_drive_get_name(drive);
    icon = g_drive_get_icon(drive);
    icon_string = g_icon_to_string(icon);
    g_object_unref(icon);

    g_print("\tname: %s\n\ticon: %s\n",
        name ? name : "(null)",
        icon_string ? icon_string : "(null)");

    g_free(name);
    g_free(icon_string);
}

static void on_drive_changed(GVolumeMonitor *volume_monitor, GDrive *drive, Context ctx)
{
    g_print("Drive changed:\n");
    print_drive_info(drive);
    update_drive(ctx, drive);
}

static void on_drive_connected(GVolumeMonitor *volume_monitor, GDrive *drive, Context ctx)
{
    g_print("Drive connected:\n");
    print_drive_info(drive);
    add_drive(ctx, drive);
}

static void on_drive_disconnected(GVolumeMonitor *volume_monitor, GDrive *drive, Context ctx)
{
    g_print("Drive disconnected:\n");
    print_drive_info(drive);
    remove_drive(ctx, drive);
}

static void on_refresh_clicked(GtkButton *button, Context ctx)
{
    refresh_drive_list(ctx);
}

int main(int argc, char *argv[])
{
    Context ctx;
    memset(ctx, 0, sizeof(ctx));
    gtk_init(&argc, &argv);

    ctx->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(ctx->window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    ctx->vbox = gtk_vbox_new(FALSE, 0);
    gtk_widget_show(ctx->vbox);
    gtk_container_add(GTK_CONTAINER(ctx->window), ctx->vbox);

    ctx->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(
        GTK_SCROLLED_WINDOW(ctx->scrolled_window),
        GTK_POLICY_AUTOMATIC,
        GTK_POLICY_AUTOMATIC);
    gtk_box_pack_start(GTK_BOX(ctx->vbox), ctx->scrolled_window, TRUE, TRUE, 0);
    gtk_widget_show(ctx->scrolled_window);

    ctx->monitor = g_volume_monitor_get();
    g_signal_connect(ctx->monitor, "drive-changed", G_CALLBACK(on_drive_changed), ctx);
    g_signal_connect(ctx->monitor, "drive-connected", G_CALLBACK(on_drive_connected), ctx);
    g_signal_connect(ctx->monitor, "drive-disconnected", G_CALLBACK(on_drive_disconnected), ctx);

    init_drive_list(ctx);
    init_drive_view(ctx);
    gtk_widget_show(ctx->view);
    gtk_container_add(GTK_CONTAINER(ctx->scrolled_window), ctx->view);

    ctx->button = gtk_button_new_from_stock(GTK_STOCK_REFRESH);
    g_signal_connect(ctx->button, "clicked", G_CALLBACK(on_refresh_clicked), ctx);
    gtk_widget_show(ctx->button);
    gtk_box_pack_start(GTK_BOX(ctx->vbox), ctx->button, FALSE, FALSE, 0);

    gtk_window_set_default_size(GTK_WINDOW(ctx->window), 500, 500);
    gtk_widget_show(ctx->window);

    gtk_main();
    return 0;
}

Compiler avec gcc $(pkg-config --cflags --libs gtk+-2.0) volumes.c -o volumes. Testez-le en exécutant, puis le brancher dans un stylo lecteur. Il devrait mettre à jour à la volée. Il affiche même des icônes appropriées.

Notez que cela surveille les lecteurs, pas montures. GVolumeMonitor peut surveiller les montures ainsi (voir « monter ajoutée » et « monter grattées » dans devhelp). Vous devrez apprendre un peu plus sur le système GObject à utiliser. Bonne chance!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top