简体   繁体   English

crypt的unistd.h和crypt.h有什么区别?

[英]What is the difference between crypt in unistd.h and crypt.h?

Background 背景

crypt has two definitions, from the docs, crypt有两个定义, 来自docs,

  1. One of them uses unistd.h 其中一个使用unistd.h

     #define _XOPEN_SOURCE /* See feature_test_macros(7) */ #include <unistd.h> 

    This is defined as 这被定义为

     #ifdef __USE_MISC extern char *crypt (const char *__key, const char *__salt) __THROW __nonnull ((1, 2)); #endif 
  2. One of them uses GNU crypt.h 其中一个使用GNU crypt.h

     #define _GNU_SOURCE /* See feature_test_macros(7) */ #include <crypt.h> 

    This is defined as 这被定义为

     extern char *crypt (const char *__phrase, const char *__salt) __THROW __nonnull ((1, 2)); 

Problem 问题

When I compile with the definition in the first example ( unistd.h ) 当我用第一个例子中的定义编译时( unistd.h

#define _XOPEN_SOURCE
#include <unistd.h>                                                                                                                                  
#include <stdio.h>                                                                                                                                   

int main()                                                                                                                                           
{                                                                                                                                                    
  printf("%s", crypt("foobar", "sa"));                                                                                                               
}

I'm getting the error 我收到了错误

In function ‘main’:
warning: implicit declaration of function ‘crypt’; did you mean ‘chroot’? [-Wimplicit-function-declaration]
  printf("%s", crypt("foobar", "sa"));
               ^~~~~
               chroot
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
  printf("%s", crypt("foobar", "sa"));
          ~^   ~~~~~~~~~~~~~~~~~~~~~
          %d

Out of desperation, I've tried adding this. 出于绝望,我尝试添加这个。

#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1

On Ubuntu Trusty 14.04 I believe this works fine use the unistd.h declaration, which makes all the more confusing. 在Ubuntu Trusty 14.04上,我相信这可以很好地使用unistd.h声明,这使得更加混乱。

These are two declarations , not two definitions . 这是两个声明 ,而不是两个定义 The content of the header file has no impact on which definition of a function is included: this is determined by the linker. 头文件的内容对包含函数定义没有影响:这由链接器决定。 There is only one definition of the crypt function in the Unix C standard library, it's whatever the symbol crypt points to in libcrypt.a or libcrypt.so (depending on whether you link statically or dynamically). 在Unix C标准库中只有一个crypt函数的定义,它是libcrypt.alibcrypt.so符号crypt指向的内容(取决于您是静态链接还是动态链接)。

Since the two declarations are compatible, it doesn't matter which header a program gets its through. 由于这两个声明是兼容的,因此程序通过哪个标头并不重要。 It's also fine if both declarations are processed: a program can contain any number of declarations for a function as long as they're compatible. 如果两个声明都被处理,那也没关系:一个程序可以包含任意数量的函数声明,只要它们兼容即可。 Without going into the exact details (refer to the C language specification), two function declarations are compatible if they have the same return type, the same number of arguments and the same type for each argument. 在没有详细说明(参考C语言规范)的情况下,如果两个函数声明具有相同的返回类型,相同数量的参数以及每个参数的相同类型,则它们是兼容的。 The name of the argument given in a declaration is not significant. 声明中给出的参数名称并不重要。

You should ignore unistd.h . 你应该忽略unistd.h That declaration is there for POSIX compatibility but GLIB has removed the definition for crypt when they migrated to libxcrypt to develop those features in isolation of glibc. 该声明适用于POSIX兼容性,但GLIB在迁移到libxcrypt时删除了crypt的定义,以便在libxcrypt使用glibc的情况下开发这些功能。 This means you can still get ABI-compatibility but must link in the crypt . 这意味着您仍然可以获得ABI兼容性,但必须链接到crypt You can read more about that here 你可以在这里阅读更多相关信息

Availability in glibc glibc中的可用性

The crypt () , encrypt () , and setkey () functions are part of the POSIX.1-2008 XSI Options Group for Encryption and are optional. crypt ()encrypt ()setkey ()函数是POSIX.1-2008 XSI加密组选项组的一部分,是可选的。 If the interfaces are not available then the symbolic constant _XOPEN_CRYPT is either not defined or defined to -1, and can be checked at runtime with sysconf () . 如果接口不可用,则符号常量_XOPEN_CRYPT未定义或定义为-1,并且可以在运行时使用sysconf ()进行检查。

This may be the case if the downstream distribution has switched from glibc crypt to libxcrypt . 如果下游分发已从glibc crypt切换到libxcrypt则可能是这种情况。 When recompiling applications in such distributions the user must detect if _XOPEN_CRPYT is not available and include crypt.h for the function prototypes; 在这种发行版中重新编译应用程序时,用户必须检测_XOPEN_CRPYT是否不可用,并为函数原型包含crypt.h; otherwise libxcrypt is a ABI compatible drop-in replacement. 否则libxcrypt是ABI兼容的直接替代品。

As for why even if you link the definition isn't pulled down with 至于为什么即使你链接定义也没有被拉下来

#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
#define _XOPEN_SOURCE

Well there are a few things that happening there 那里发生了一些事情

  1. The only header that matters in unistd.h is __USE_MISC . unistd.h唯一重要的标题是__USE_MISC
  2. unistd.h includes features.h which undef s the __USE_ macros to start with a "clean slate" unistd.h包括features.hundef S中__USE_宏开始一个“清白”
  3. The only way to define __USE_MISC is to have defined _GNU_SOURCE . 定义__USE_MISC的唯一方法是定义_GNU_SOURCE

If you want to pull in the declaration of crypt.h from unistd.h you must define _GNU_SOURCE ! 如果你想从unistd.hcrypt.h的声明,你必须定义_GNU_SOURCE Those two examples cited from man page of crypt.h do the same thing and whether you include unistd.h or crypt.h you MUST also define _GNU_SOURCE in contemporary versions of glibc. crypt.h man页面引用的这两个例子做同样的事情,无论你是否包含unistd.hcrypt.h你还必须在当前版本的glibc中定义_GNU_SOURCE

So you can either do, 所以你可以这样做,

#define _GNU_SOURCE
#include <unistd.h>

Or, 要么,

#define _GNU_SOURCE
#include <crypt.h>

But because you must link against crypt ( -lcrypt ) I would suggest using the declaration in crypt.h for sanity. 但是因为你必须链接crypt-lcrypt ),我建议使用crypt.h的声明来保持理智。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM