2009-10-03 21 views

Respuesta

23

Las funciones de Microsoft *_s no son portables, generalmente uso funciones C89/C99 equivalentes y desactivo las advertencias de desactivación (#define _CRT_SECURE_NO_DEPRECATE).

Si insiste, se puede utilizar una función de adaptador (no necesariamente una macro!) Que los delegados fopen() en plataformas que no tienen fopen_s(), pero hay que tener cuidado al asignar los valores de código de retorno de errno_terrno.

errno_t fopen_s(FILE **f, const char *name, const char *mode) { 
    errno_t ret = 0; 
    assert(f); 
    *f = fopen(name, mode); 
    /* Can't be sure about 1-to-1 mapping of errno and MS' errno_t */ 
    if (!*f) 
     ret = errno; 
    return ret; 
} 

Sin embargo, no veo cómo fopen_s() es más segura que la fopen(), por lo que suelen ir para la portabilidad.

+5

Microsoft AMA hacer su propia versión de las cosas. Me pregunto por qué ... – LiraNuna

+9

Lo curioso es que ahora son parte de C11 (aunque en el Anexo K opcional) – rubenvb

+0

Mucho mejor que mi (ahora anterior, no es que lo necesite más) puro enfoque macro.El enfoque de su función reproduce parcialmente el comportamiento de fopen_s en caso de error devolviendo errno (= EINVAL, es decir, 22, fwiw). También podría generar una * excepción de parámetro inválido * para hacer coincidir el comportamiento de fopen_s aún más de cerca. – riderBill

4

En código C/C++,

#ifdef __unix 
#define fopen_s(pFile,filename,mode) ((*(pFile))=fopen((filename),(mode)))==NULL 
#endif 

En Makefile

CFLAGS += -D'fopen_s(pFile,filename,mode)=((*(pFile))=fopen((filename),(mode)))==NULL' 

atención que en caso de éxito fopen_s devolver 0, mientras que fopen devuelve un puntero a un archivo distinto de cero. Por lo tanto es necesario añadir "== NULL" al final de la macro, por ejemplo:

if (fopen_s(&pFile,filename,"r")) perror("cannot open file"); 
1

Muchas de las funciones seguras de Microsoft están incluidas en el anexo K del estándar C11, pero no es ampliamente compatible, por lo que la portabilidad sigue siendo un problema. Es necesario mejorar la seguridad en algunas aplicaciones; tal vez el soporte mejorará en el futuro.

que el pasado, lo hice así:

#define fopen_s(fp, fmt, mode)   *(fp)=fopen((fmt), (mode)) 

La macro es simple y sencillo, lo suficientemente bueno para algo rápido y sucio, pero no proporciona el comportamiento excepción de fopen_s, y no proporcionará la seguridad de la función fopen_s real.

@El enfoque de la función de Alex B arriba reproduce parcialmente el comportamiento correcto en caso de falla; él devuelve errno (= EINVAL). Su enfoque podría ampliarse aún más mediante la generación de una excepción de parámetro no válido para reproducir de forma más completa el comportamiento de fopen_s.

Cuestiones relacionadas