La respuesta es que no puede, a menos que su sistema de archivos tenga un error. Este es el por qué:
Hay una llamada al sistema para cambiar el nombre de su archivo definido en fs/namei.c
llamado renameat
:
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname)
Cuando se invoca la llamada al sistema, realiza una búsqueda de ruta ( do_path_lookup
) en el nombre. Siga rastreando esto, y llegamos a lo link_path_walk
que tiene esto:
static int link_path_walk(const char *name, struct nameidata *nd)
{
struct path next;
int err;
unsigned int lookup_flags = nd->flags;
while (*name=='/')
name++;
if (!*name)
return 0;
...
Este código se aplica a cualquier sistema de archivos. ¿Que significa esto? Significa que si intenta pasar un parámetro con un '/'
carácter real como nombre del archivo usando medios tradicionales, no hará lo que desea. No hay forma de escapar del personaje. Si un sistema de archivos "admite" esto, es porque:
- Utilice un carácter Unicode o algo que parezca una barra pero no lo sea.
- Tienen un error.
Por otra parte, si lo hizo entrar y editar los bytes añadir un carácter de barra en un nombre de archivo, las cosas malas que pasaría. Eso es porque nunca podrías referirte a este archivo por su nombre :( ya que siempre que lo hicieras, Linux supondría que te refieres a un directorio inexistente. Usar la técnica 'rm *' tampoco funcionaría, ya que bash simplemente expande eso al nombre del archivo. Incluso rm -rf
no funcionaría, ya que un simple strace revela cómo van las cosas bajo el capó (abreviado):
$ ls testdir
myfile2 out
$ strace -vf rm -rf testdir
...
unlinkat(3, "myfile2", 0) = 0
unlinkat(3, "out", 0) = 0
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(3) = 0
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0
...
Tenga en cuenta que estas llamadas a unlinkat
fallarían porque necesitan hacer referencia a los archivos por su nombre.