EDIT: J'ai réécrit cette question, car je n'ai pas de réponse et j'essaie actuellement de réduire le problème.mysql UDF: fopen = permission refusée
J'essaye de créer un mysql UDF function vérifiant si un dossier existe du côté de serveur. Cette fonction appelle "ouvrir/fermer". Cela ne fonctionne pas même lorsque le fichier est lisible.
Je mets le code pour cette fonction ci-dessous:
#include <mysql.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
/* The initialization function */
my_bool fileExists_init(
UDF_INIT *initid,
UDF_ARGS *args,
char *message
)
{
/* check the args */
if (!(args->arg_count == 1 &&
args->arg_type[0] == STRING_RESULT
))
{
strncpy(message,"Bad parameter expected a string",MYSQL_ERRMSG_SIZE);
return 1;
}
initid->maybe_null=1;
initid->ptr= NULL;
return 0;
}
/* The deinitialization function */
void fileExists_deinit(UDF_INIT *initid)
{
}
#define MAX_RESULT_LENGTH 250
char *fileExists(
UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error)
{
//bad filename
if(args->args[0]==NULL || args->lengths[0]==0 || args->lengths[0] >= FILENAME_MAX)
{
strncpy(result,"#BAD_INPUT",MAX_RESULT_LENGTH);
}
else
{
char filename[FILENAME_MAX+1];
int err;
int in;
//create a NULL terminated string
memcpy(filename,args->args[0],args->lengths[0]);
filename[args->lengths[0]]=0;
errno=0;
in=open(filename,O_RDONLY|O_NDELAY);
err=errno;
if(in<0)
{
snprintf(result,MAX_RESULT_LENGTH,"#ERR:\"%s\":\"%s\".",strerror(err),filename);
}
else
{
close(in);
snprintf(result,MAX_RESULT_LENGTH,"OK:\"%s\".",filename);
}
}
*length=strlen(result);
return result;
}
Marque:
gcc -Wall -DMYSQL_VERSION -fPIC -shared `mysql_config --cflags` -o `mysql_config --plugindir`/libfileexists.so udffileexists.c `mysql_config --libs `
test:
ok, MySQL peut ouvrir des fichiers:
mysql> create function fileExists RETURNS STRING SONAME 'libfileexists.so'; select fileExists("/etc/mysql/my.cnf"); drop function fileExists;
Query OK, 0 rows affected (0.00 sec)
+---------------------------------+
| fileExists("/etc/mysql/my.cnf") |
+---------------------------------+
| OK:"/etc/mysql/my.cnf". |
+---------------------------------+
1 row in set (0.00 sec)
mysql> create function fileExists RETURNS STRING SONAME 'libfileexists.so'; select fileExists("/tmp/file.txt"); drop function fileExists;
Query OK, 0 rows affected (0.00 sec)
+-------------------------------+
| fileExists("/tmp/file.txt") |
+-------------------------------+
| OK:"/tmp/file.txt". |
+-------------------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
OK, pas de problème, ça marche s, je peux ouvrir() file.txt dans /tmp/
ls -la /tmp
drwxrwxrwt 16 root root 4096 2010-05-28 15:45 .
-rw-r--r-- 1 lindenb lindenb 0 2010-05-28 15:25 file.txt
Mais quand je veux tester un fichier dans /données:
ls -la /data
drwxrwxrwx 4 root root 4096 2010-05-28 16:11 .
-rw-r--r-- 1 lindenb lindenb 0 2010-05-28 15:25 file.txt
Je suis:
mysql> create function fileExists RETURNS STRING SONAME 'libfileexists.so'; select fileExists("/data/file.txt"); drop function fileExists;
Query OK, 0 rows affected (0.00 sec)
+--------------------------------------------+
| fileExists("/data/file.txt") |
+--------------------------------------------+
| #ERR:"Permission denied":"/data/file.txt". |
+--------------------------------------------+
1 row in set (0.00 sec)
Une idée?
Merci!
open() renvoie -1 en cas d'erreur qui se trouve être -EACCESS (sur OS X au moins). Ce que vous voulez probablement, c'est strerror (errno).Pouvez-vous mettre à jour si cela rend l'erreur rapportée différente? –
@Paul, c'est ce que j'ai vu: "strerror (err)" (j'ai tout d'abord rapidement copié errno pour errer car l'utilisation d'errno dans un programme MT est une mauvaise pratique). J'ai aussi essayé d'utiliser fopen plutôt qu'ouvert. cela donne le même type de résultat (in == NULL). Je cours sur mon localhost, ubuntu – Pierre
Avez-vous essayé de su'ing à l'utilisateur exécutant MySQL pour vérifier qu'ils peuvent lire ce dossier? Vos autorisations semblent correctes à la lecture, mais c'est toujours une bonne vérification. –