Existe uma maneira de usar fopen_s () com GCC ou pelo menos criar um #define sobre isso?

StackOverflow https://stackoverflow.com/questions/1513209

  •  19-09-2019
  •  | 
  •  

Pergunta

compilador MSVC diz que fopen() está obsoleta, e recomenda o uso de fopen_s().

Existe alguma maneira de usar fopen_s() e ainda ser portátil?

Todas as idéias para um #define?

Foi útil?

Solução

funções *_s da Microsoft são portável, eu costumo usar equivalentes funções C89 / C99 e desativar os avisos de descontinuação (#define _CRT_SECURE_NO_DEPRECATE).

Se você insistir, você pode usar uma função de adaptador (não necessariamente uma macro!) Que os delegados fopen() em plataformas que não têm fopen_s(), mas você deve ter cuidado para mapear valores de código errno_t retorno de errno.

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;
}

No entanto, eu não consigo ver como fopen_s() é mais seguro do que fopen(), então eu costumo ir para a portabilidade.

Outras dicas

Se você estiver usando C11, fopen_s é uma biblioteca padrão:

http://en.cppreference.com/w/c/io/fopen

em gcc você precisa usar o parâmetro --std=C11.

código em C / C ++,

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

Em Makefile

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

Atenção que na fopen_s sucesso retornar 0 enquanto o retorno fopen um ponteiro de arquivo diferente de zero. Por isso, é necessário adicionar "== null" para o fim da macro, por exemplo:.

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

Muitas das funções seguras da Microsoft estão incluídas no anexo K do padrão C11, mas não é amplamente apoiada, de modo a portabilidade ainda é um problema. Há uma necessidade para a melhoria da segurança em algumas aplicações; talvez o apoio vai melhorar no futuro.

I passado, eu fiz assim:

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

A macro é simples e direta, bom o suficiente para uma rápida algo e sujo, mas não fornece o comportamento exceção de fopen_s, e que não irá fornecer a segurança da função fopen_s real.

abordagem da função de @Alex B acima parcialmente reproduz o comportamento adequado em caso de falha; ele retorna errno (= EINVAL). Sua abordagem pode ser estendido ainda mais, gerando um parâmetro inválido exceção para reproduzir mais plenamente o comportamento de fopen_s.

#define fopen_s(fp, fmt, mode)  ({\
    *(fp)=fopen( (fmt), (mode));\
    (*(fp) ) ? 0:errno;\
})

Accroding para https://en.cppreference.com/w/c/io / fopen é possível habilitar * _s funções na biblioteca padrão:

Tal como acontece com todas as funções Bounds-verificados, fopen_s só é garantido para estar disponível se __STDC_LIB_EXT1__ é definida pela implementação e se os define usuário __STDC_WANT_LIB_EXT1__ para o inteiro constante 1 antes de incluir <stdio.h>.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top