je cherche (dans un programme C++) à déplacer un fichier d'une partition
à l'autre, ce qui n'est pas possible avec la fonction rename(), qui
renvoit dans ce cas l'erreur "Invalid cross-device link".
J'ai cherché dans google, regardé dans la glib, dans les sources du
programme mv:
* google: recherches infructueuses, je dois être trop bête pour trouver
la requête qui va bien.
* glib: la commande g_rename ne fait rien de plus qu'appeler rename, ce
qui ne m'avance pas :-)
* mv: c'est un peu trop complexe pour un "déplacement de rien du tout" ;-)
je cherche (dans un programme C++) à déplacer un fichier d'une partition à l'autre, ce qui n'est pas possible avec la fonction rename(), qui renvoit dans ce cas l'erreur "Invalid cross-device link".
Correct, déplacer un fichier d'un système de fichier à un autre ne peut pas être effectué par un simple renommage, c'est à dire sans déplacement des données.
J'ai cherché dans google, regardé dans la glib, dans les sources du programme mv: * google: recherches infructueuses, je dois être trop bête pour trouver la requête qui va bien. * glib: la commande g_rename ne fait rien de plus qu'appeler rename, ce qui ne m'avance pas :-) * mv: c'est un peu trop complexe pour un "déplacement de rien du tout" ;-)
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source.
Robert CHERAMY wrote:
Bonjour,
je cherche (dans un programme C++) à déplacer un fichier d'une partition
à l'autre, ce qui n'est pas possible avec la fonction rename(), qui
renvoit dans ce cas l'erreur "Invalid cross-device link".
Correct, déplacer un fichier d'un système de fichier à un autre ne
peut pas être effectué par un simple renommage, c'est à dire sans
déplacement des données.
J'ai cherché dans google, regardé dans la glib, dans les sources du
programme mv:
* google: recherches infructueuses, je dois être trop bête pour trouver
la requête qui va bien.
* glib: la commande g_rename ne fait rien de plus qu'appeler rename, ce
qui ne m'avance pas :-)
* mv: c'est un peu trop complexe pour un "déplacement de rien du tout" ;-)
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie
de l'effacement du fichier source.
je cherche (dans un programme C++) à déplacer un fichier d'une partition à l'autre, ce qui n'est pas possible avec la fonction rename(), qui renvoit dans ce cas l'erreur "Invalid cross-device link".
Correct, déplacer un fichier d'un système de fichier à un autre ne peut pas être effectué par un simple renommage, c'est à dire sans déplacement des données.
J'ai cherché dans google, regardé dans la glib, dans les sources du programme mv: * google: recherches infructueuses, je dois être trop bête pour trouver la requête qui va bien. * glib: la commande g_rename ne fait rien de plus qu'appeler rename, ce qui ne m'avance pas :-) * mv: c'est un peu trop complexe pour un "déplacement de rien du tout" ;-)
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source.
Robert CHERAMY
Jean-Louis Liagre wrote:
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source. Snif... moi qui pensait m'en sortir plus facilement...
Pour info, il semble que QT4 fait le travail pour vous avec la fonction QFile::rename(). Mais tout le monde ne peut utiliser C++ et QT4 (surtout quand on ne fait que corriger un bug...)
Merci Jean-Louis et A+,
tibob
Jean-Louis Liagre wrote:
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie
de l'effacement du fichier source.
Snif... moi qui pensait m'en sortir plus facilement...
Pour info, il semble que QT4 fait le travail pour vous avec la fonction
QFile::rename(). Mais tout le monde ne peut utiliser C++ et QT4 (surtout
quand on ne fait que corriger un bug...)
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source. Snif... moi qui pensait m'en sortir plus facilement...
Pour info, il semble que QT4 fait le travail pour vous avec la fonction QFile::rename(). Mais tout le monde ne peut utiliser C++ et QT4 (surtout quand on ne fait que corriger un bug...)
Merci Jean-Louis et A+,
tibob
Fred
Jean-Louis Liagre wrote:
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source.
Snif... moi qui pensait m'en sortir plus facilement...
Pour info, il semble que QT4 fait le travail pour vous avec la fonction QFile::rename(). Mais tout le monde ne peut utiliser C++ et QT4 (surtout quand on ne fait que corriger un bug...)
La commande mv fait un cp et un rm lorsque les partitions de départ et d'arrivée sont différentes.
A+
Jean-Louis Liagre wrote:
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie
de l'effacement du fichier source.
Snif... moi qui pensait m'en sortir plus facilement...
Pour info, il semble que QT4 fait le travail pour vous avec la fonction
QFile::rename(). Mais tout le monde ne peut utiliser C++ et QT4 (surtout
quand on ne fait que corriger un bug...)
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source.
Snif... moi qui pensait m'en sortir plus facilement...
Pour info, il semble que QT4 fait le travail pour vous avec la fonction QFile::rename(). Mais tout le monde ne peut utiliser C++ et QT4 (surtout quand on ne fait que corriger un bug...)
Il n'était pas question de sécurité dans le cahier des charges ;) A+ Fred
Antoine Leca
In news:dr0jdj$6b4$, Robert CHERAMY va escriure:
Jean-Louis Liagre wrote:
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source. Snif... moi qui pensait m'en sortir plus facilement...
Bah non, pas possible. Deux systèmes de fichiers sont physiquement distincts. Donc il faut physiquement écrire le contenu du fichier dans le système de destination (opération de copie de fichier), et [ensuite] physiquement libérer l'espace sur le système source (opération d'effacement).
Si vous avez une autre solution, vous allez droit au Nobel.
Antoine
In news:dr0jdj$6b4$1@poulet.zoy.org, Robert CHERAMY va escriure:
Jean-Louis Liagre wrote:
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie
de l'effacement du fichier source.
Snif... moi qui pensait m'en sortir plus facilement...
Bah non, pas possible.
Deux systèmes de fichiers sont physiquement distincts. Donc il faut
physiquement écrire le contenu du fichier dans le système de destination
(opération de copie de fichier), et [ensuite] physiquement libérer l'espace
sur le système source (opération d'effacement).
Si vous avez une autre solution, vous allez droit au Nobel.
C'est pourtant ce qu'il faut faire: une recopie du fichier suivie de l'effacement du fichier source. Snif... moi qui pensait m'en sortir plus facilement...
Bah non, pas possible. Deux systèmes de fichiers sont physiquement distincts. Donc il faut physiquement écrire le contenu du fichier dans le système de destination (opération de copie de fichier), et [ensuite] physiquement libérer l'espace sur le système source (opération d'effacement).
Si vous avez une autre solution, vous allez droit au Nobel.
Antoine
Nicolas George
Fred wrote in message <dr2oa7$js3$:
Il n'était pas question de sécurité dans le cahier des charges ;)
Il est _toujours_ question de sécurité quand on programme.
Accessoirement, ta solution se vautre sur les fichiers dont le nom comporte un espace.
Fred wrote in message
<dr2oa7$js3$1@smb-pub.grenoble.si.fr.atosorigin.com>:
Il n'était pas question de sécurité dans le cahier des charges ;)
Il est _toujours_ question de sécurité quand on programme.
Accessoirement, ta solution se vautre sur les fichiers dont le nom comporte
un espace.
Il n'était pas question de sécurité dans le cahier des charges ;)
Un trou de sécurité sans attaquant, ça reste un bug. Il y en a certes où il faut le faire exprès pour tomber dedans, mais celui-là, non, il est vraiment béhant.
Il n'était pas question de sécurité dans le cahier des charges ;)
Un trou de sécurité sans attaquant, ça reste un bug. Il y en a certes où il
faut le faire exprès pour tomber dedans, mais celui-là, non, il est vraiment
béhant.
Il n'était pas question de sécurité dans le cahier des charges ;)
Un trou de sécurité sans attaquant, ça reste un bug. Il y en a certes où il faut le faire exprès pour tomber dedans, mais celui-là, non, il est vraiment béhant.
Il n'était pas question de sécurité dans le cahier des charges ;)
Tu mènes quand même une vie dangereuse...
1 - system( ) n'est pas très sûr, surtout si on est suid / sgid. on ne peut guère l'employer que lorsqu'on est sûr que le programme ne sera pas utilisé dans ces conditions, c'est à dire pas très souvent. Utiliser plutôt fork( ), execv( )/execve( ), waitpid( ). 2 - sprintf( ) mérite un peu d'attention dans son emploi. Ici, c'est un des cas où il peut être utilisé car la taille de la chaîne résultante est prévisible.
Si tu tiens à utiliser system( ), ce qui peut peut-être (?) se concevoir dans ce cas, il faut prendre un minimum de précautions. Voilà un petit programme qui appelle mv et s'utilise comme mv :
Il n'était pas question de sécurité dans le cahier des charges ;)
Tu mènes quand même une vie dangereuse...
1 - system( ) n'est pas très sûr, surtout si on est suid / sgid. on ne
peut guère l'employer que lorsqu'on est sûr que le programme ne sera
pas utilisé dans ces conditions, c'est à dire pas très souvent.
Utiliser plutôt fork( ), execv( )/execve( ), waitpid( ).
2 - sprintf( ) mérite un peu d'attention dans son emploi. Ici, c'est un
des cas où il peut être utilisé car la taille de la chaîne résultante
est prévisible.
Si tu tiens à utiliser system( ), ce qui peut peut-être (?) se concevoir
dans ce cas, il faut prendre un minimum de précautions.
Voilà un petit programme qui appelle mv et s'utilise comme mv :
Il n'était pas question de sécurité dans le cahier des charges ;)
Tu mènes quand même une vie dangereuse...
1 - system( ) n'est pas très sûr, surtout si on est suid / sgid. on ne peut guère l'employer que lorsqu'on est sûr que le programme ne sera pas utilisé dans ces conditions, c'est à dire pas très souvent. Utiliser plutôt fork( ), execv( )/execve( ), waitpid( ). 2 - sprintf( ) mérite un peu d'attention dans son emploi. Ici, c'est un des cas où il peut être utilisé car la taille de la chaîne résultante est prévisible.
Si tu tiens à utiliser system( ), ce qui peut peut-être (?) se concevoir dans ce cas, il faut prendre un minimum de précautions. Voilà un petit programme qui appelle mv et s'utilise comme mv :
#define FORMAT "/bin/mv %s %s" #define FORMAT_SIZE ( sizeof( FORMAT ) - 5 )
int main( int argc, char ** argv ){ char * cmd = NULL; char * from; char * to; size_t len; int rc;
if ( argc < 3 ) { fprintf( stderr, "Not enough arguments.n" ); fprintf( stderr, "usage : mymove from-file to-filen" ); return( EXIT_FAILURE ); } from = *(argv + 1); to = *(argv + 2); len = FORMAT_SIZE + strlen( from ) + strlen( to ); cmd = malloc( len + 1 ); if ( cmd == NULL ) { fprintf( stderr, "Cannot allocate memory for mv commandn" ); return( EXIT_FAILURE ) ; } rc = sprintf( cmd, FORMAT, from, to ); if ( rc != (int) len ) { fprintf( stderr, "sprintf failed rc=%dn", rc ); return( EXIT_FAILURE ) ; } rc = system( cmd ); if ( rc ) { fprintf( stderr, "Cannot execute command below rc=%d :n'%s'n", WEXITSTATUS( rc ), cmd ); if ( WIFSIGNALED( rc ) ) { fprintf( stderr, "Killed by signal %d.n", WTERMSIG( rc ) ); } return( EXIT_FAILURE ) ; } return( EXIT_SUCCESS ) ; } -----------------------------
Loïc Restoux
Le 28 jan, à 10:36, Harpo papotait :
Tu mènes quand même une vie dangereuse...
Hmmmm... voyons... (Attention, je vais etre HS).
2 - sprintf( ) mérite un peu d'attention dans son emploi. Ici, c'est un des cas où il peut être utilisé car la taille de la chaîne résultante est prévisible.
[SNIP]
----------------------------- #define FORMAT "/bin/mv %s %s" #define FORMAT_SIZE ( sizeof( FORMAT ) - 5 ) ^^^^^
Aie : - La constante FORMAT_SIZE ne contient donc *pas* la taille de la constante FORMAT. Mauvais nommage. - On a le nombre 5 en dur, si quelqu'un modifie la chaine de format sans chercher à comprendre, ça ne marchera plus. - Dans les calculs qui suivent, on perd l'espace séparateur entre les deux arguments...
int main( int argc, char ** argv ){ char * cmd = NULL; char * from; char * to; size_t len; int rc;
if ( argc < 3 ) { fprintf( stderr, "Not enough arguments.n" ); fprintf( stderr, "usage : mymove from-file to-filen" ); return( EXIT_FAILURE ); } from = *(argv + 1); to = *(argv + 2); len = FORMAT_SIZE + strlen( from ) + strlen( to );
Ici, len ne tient pas compte du fameux espace séparateur des deux arguments. Par contre, on y trouve le caractère terminal de la chaine de format.
cmd = malloc( len + 1 );
Pour quoi +1, puisque l'on a compté le caractère terminal de la chaine de format ? Coup de bol, ça rattrape le fameux espace que l'on avait perdu en cours de route.
if ( cmd == NULL ) { fprintf( stderr, "Cannot allocate memory for mv commandn" ); return( EXIT_FAILURE ) ; } rc = sprintf( cmd, FORMAT, from, to ); if ( rc != (int) len ) { fprintf( stderr, "sprintf failed rc=%dn", rc ); return( EXIT_FAILURE ) ; }
Ca rentre pile poil. On a eu chaud.
Ou alors, c'était fait exprès dès le départ, mais dans ce cas là, je plains franchement le mainteneur du bout de code, il va avoir du mal à retrouver ces petits.
Et puis, ça manque de commentaires. :)
-- No fortunes found
Le 28 jan, à 10:36, Harpo papotait :
Tu mènes quand même une vie dangereuse...
Hmmmm... voyons...
(Attention, je vais etre HS).
2 - sprintf( ) mérite un peu d'attention dans son emploi. Ici, c'est un
des cas où il peut être utilisé car la taille de la chaîne résultante
est prévisible.
[SNIP]
-----------------------------
#define FORMAT "/bin/mv %s %s"
#define FORMAT_SIZE ( sizeof( FORMAT ) - 5 )
^^^^^
Aie :
- La constante FORMAT_SIZE ne contient donc *pas* la taille de la
constante FORMAT. Mauvais nommage.
- On a le nombre 5 en dur, si quelqu'un modifie la chaine de format sans
chercher à comprendre, ça ne marchera plus.
- Dans les calculs qui suivent, on perd l'espace séparateur entre les
deux arguments...
int main( int argc, char ** argv ){
char * cmd = NULL;
char * from;
char * to;
size_t len;
int rc;
if ( argc < 3 ) {
fprintf( stderr, "Not enough arguments.n" );
fprintf( stderr, "usage : mymove from-file to-filen" );
return( EXIT_FAILURE );
}
from = *(argv + 1);
to = *(argv + 2);
len = FORMAT_SIZE + strlen( from ) + strlen( to );
Ici, len ne tient pas compte du fameux espace séparateur des deux
arguments. Par contre, on y trouve le caractère terminal de la chaine de
format.
cmd = malloc( len + 1 );
Pour quoi +1, puisque l'on a compté le caractère terminal de la chaine
de format ? Coup de bol, ça rattrape le fameux espace que l'on avait
perdu en cours de route.
if ( cmd == NULL ) {
fprintf( stderr, "Cannot allocate memory for mv commandn" );
return( EXIT_FAILURE ) ;
}
rc = sprintf( cmd, FORMAT, from, to );
if ( rc != (int) len ) {
fprintf( stderr, "sprintf failed rc=%dn", rc );
return( EXIT_FAILURE ) ;
}
Ca rentre pile poil. On a eu chaud.
Ou alors, c'était fait exprès dès le départ, mais dans ce cas là, je
plains franchement le mainteneur du bout de code, il va avoir du mal à
retrouver ces petits.
2 - sprintf( ) mérite un peu d'attention dans son emploi. Ici, c'est un des cas où il peut être utilisé car la taille de la chaîne résultante est prévisible.
[SNIP]
----------------------------- #define FORMAT "/bin/mv %s %s" #define FORMAT_SIZE ( sizeof( FORMAT ) - 5 ) ^^^^^
Aie : - La constante FORMAT_SIZE ne contient donc *pas* la taille de la constante FORMAT. Mauvais nommage. - On a le nombre 5 en dur, si quelqu'un modifie la chaine de format sans chercher à comprendre, ça ne marchera plus. - Dans les calculs qui suivent, on perd l'espace séparateur entre les deux arguments...
int main( int argc, char ** argv ){ char * cmd = NULL; char * from; char * to; size_t len; int rc;
if ( argc < 3 ) { fprintf( stderr, "Not enough arguments.n" ); fprintf( stderr, "usage : mymove from-file to-filen" ); return( EXIT_FAILURE ); } from = *(argv + 1); to = *(argv + 2); len = FORMAT_SIZE + strlen( from ) + strlen( to );
Ici, len ne tient pas compte du fameux espace séparateur des deux arguments. Par contre, on y trouve le caractère terminal de la chaine de format.
cmd = malloc( len + 1 );
Pour quoi +1, puisque l'on a compté le caractère terminal de la chaine de format ? Coup de bol, ça rattrape le fameux espace que l'on avait perdu en cours de route.
if ( cmd == NULL ) { fprintf( stderr, "Cannot allocate memory for mv commandn" ); return( EXIT_FAILURE ) ; } rc = sprintf( cmd, FORMAT, from, to ); if ( rc != (int) len ) { fprintf( stderr, "sprintf failed rc=%dn", rc ); return( EXIT_FAILURE ) ; }
Ca rentre pile poil. On a eu chaud.
Ou alors, c'était fait exprès dès le départ, mais dans ce cas là, je plains franchement le mainteneur du bout de code, il va avoir du mal à retrouver ces petits.