Si realmente está decidido a cambiar el comportamiento de este programa (de la que supongo que usted no tiene el código fuente disponible), puede utilizar LD_PRELOAD
para conectar la llamada a opendir
y readdir
y reemplazarlo con su propio, sorter de clasificación. Un ejemplo de cómo un gancho de este tipo podría ser similar es el siguiente:
#define _GNU_SOURCE 1
#include <stdio.h>
#include <dirent.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
struct __dirstream
{
int __fd;
char *__data;
size_t __allocation;
size_t __offset;
size_t __size;
struct dirent __entry;
};
typedef struct _dirent_list {
struct dirent *value;
struct _dirent_list *next;
} dirent_list;
typedef struct _my_DIR {
struct __dirstream orig;
dirent_list *first_entry;
int first_readdir;
} my_DIR;
DIR *opendir(const char *name) {
DIR *(*orig_opendir)(const char*) = dlsym(RTLD_NEXT, "opendir");
DIR *dir = orig_opendir(name);
// save additional information along with the
// original DIR structure
my_DIR *my_dir = calloc(1, sizeof(*my_dir));
my_dir->first_readdir = 1;
memcpy(my_dir, dir, sizeof(*dir));
return (DIR*)my_dir;
}
struct dirent *readdir(DIR *dir) {
struct dirent *(*orig_readdir)(DIR*) = dlsym(RTLD_NEXT, "readdir");
my_DIR *my_dir = (my_DIR*)dir;
dirent_list *item;
if (my_dir->first_readdir) {
struct dirent *entry;
while ((entry = orig_readdir(dir))) {
// exercise for the reader:
// implement insertion sort here
item = calloc(1, sizeof(*item));
item->value = entry;
item->next = my_dir->first_entry;
my_dir->first_entry = item;
}
my_dir->first_readdir = 0;
}
if (!my_dir->first_entry)
return NULL;
item = my_dir->first_entry;
struct dirent *result = item->value;
my_dir->first_entry = item->next;
free(item);
return result;
}
Se anula opendir
y readdir
para regresar las entradas en orden inverso (se puede adaptar esta para clasificar también). Esta es la forma en que lo utilice con un programa test
que se limita a enumerar las entradas de directorio en el orden en que se reciben:
$ gcc -Wall -shared -fPIC -o libhookdir.so hookdir.c -ldl
$ ./test
..
test
.
hookdir.c
libhookdir.so
test.c
$ LD_PRELOAD=./libhookdir.so ./test
test.c
libhookdir.so
hookdir.c
.
test
..
Ja! Esto funciona. Acabamos de enganchar una función de libc.
El hecho de que es ext4 seguro hace la diferencia. Para vfat, puede mover el directorio a otro sistema de archivos y luego copiar los archivos nuevamente en el orden correcto. Lo hago todo el tiempo para reproductores de mp3 portátiles. Por cierto, Shell Glob también tipo 'ls'. Entonces, 'cp -r music/media/my_player' me dará el orden incorrecto, pero' mkdir/media/my_player/music; cp -v music/*/media/my_player/music' - ¡copia los archivos correctamente! ¡Pero este truco no ayuda en ext4! (Tal vez tiene directorios hashtable o algo así ...) –
Bueno, he encontrado la misma conclusión aquí: http://superuser.com/a/373621/269542 - por lo que solo puede ordenar. Si tiene las fuentes de dicha aplicación, puede agregar la ordenación allí, en lugar de piratear con LD_PRELOAD. –