简体   繁体   English

errno、strerror 和 Linux 系统调用

[英]errno, strerror and Linux system calls

I can use strerror() to get text representation of errno value after using CRT functions, like fopen() .在使用 CRT 函数后,我可以使用strerror()来获取errno值的文本表示,例如fopen() If I use open() Linux system call instead of CRT function, it also sets errno value when it fails.如果我使用open() Linux 系统调用而不是 CRT function,它也会在失败时设置errno值。 Is this correct to apply strerror() to this errno value?strerror()应用于此errno值是否正确? If not, is there some Linux system call, which does the same as strerror() ?如果没有,是否有一些 Linux 系统调用,与strerror()相同?

Yes, and your code might be something like (untested) this: 是的,您的代码可能类似于(未经测试):

   #include <stdio.h>
   #include <errno.h>
   #include <string.h>               // declares: char *strerror(int errnum);

   FILE *
   my_fopen ( char *path_to_file, char *mode ) {
     FILE *fp;
     char *errmsg;
     if ( fp = fopen( path_to_file, mode )) {
       errmsg = strerror( errno );  // fopen( ) failed, fp is set to NULL
       printf( "%s %s\n", errmsg, path_to_file );
     } 
     else {                         // fopen( ) succeeded
     ...
     } 

     return fp;                     // return NULL (failed) or open file * on success
   }

Yes

Yes

In there is perror 在那里是perror

if (-1 == open(....))
{
    perror("Could not open input file");
    exit(255)
}

Most of the Linux system calls are encapsulated by C library routines.大多数 Linux 系统调用被 C 库例程封装。 open() system call is actually a function defined in the C library which calls the actual open() system call of the kernel. open()系统调用实际上是 C 库中定义的 function,它调用 kernel 的实际open()系统调用。

errno is a variable defined and managed by the C library, not by the kernel. errno是由 C 库而不是 kernel 定义和管理的变量。 It is set upon the return of the system call with the error code returned by the kernel.它在系统调用返回时设置,错误代码由 kernel 返回。

As an example, in the GNU C library, open() is defined in sysdeps/unix/sysv/linux/open.c as:例如,在 GNU C 库中, open()sysdeps/unix/sysv/linux/open.c中定义为:

int
__libc_open (const char *file, int oflag, ...)
{
  int mode = 0;

  if (__OPEN_NEEDS_MODE (oflag))
    {
      va_list arg;
      va_start (arg, oflag);
      mode = va_arg (arg, int);
      va_end (arg);
    }

  return SYSCALL_CANCEL (openat, AT_FDCWD, file, oflag, mode);
}
libc_hidden_def (__libc_open)

weak_alias (__libc_open, __open)
libc_hidden_weak (__open)
weak_alias (__libc_open, open)

The bottom macros establish a equivalence between __libc_open() and open() .底部的宏在__libc_open()open()之间建立了等价关系。
The SYSCALL_CANCEL() macros invokes the actual system call (which is openat() ) and sets errno with the error code if any error condition occured. SYSCALL_CANCEL()宏调用实际的系统调用(即openat() )并在发生任何错误情况时使用错误代码设置errno

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

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