How to check the value of errno?

前端 未结 3 794
野性不改
野性不改 2020-12-09 21:44

I am using a system call and in case it fails, I need to do different things for different errnos.

I need to write code that looks something like this:



        
3条回答
  •  春和景丽
    2020-12-09 22:29

    I assume you are using Linux, and I suppose that you don't directly use the system call, but some of the (simple) wrappers (from your C library) listed in syscalls(2). Notice that some weird system calls are not wrapped by the C library (a well known example of unwrapped system call would be sigreturn(2) which you probably should never use). Quite often the C library is GNU glibc, but it might be musl-libc etc. Notice also that kernel raw system calls have different calling conventions than ordinary C function (so in practice a libc wrapper is required, and is in charge of dealing with errno). Notice also that errno(3) is generally a macro (almost behaving as some variable).

    The msgrcv(2) man page documents that errno could be one of E2BIG, EACCES , EFAULT ... ENOMSG, ENOSYS ... (refer to that man page to get the list of all possible errors).

    So you would code something like

    ssize_t siz = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
    if (siz<0) { // msgrcv failed and has set errno
      if (errno == ENOMSG) 
        dosomething();
      else if (errno == EAGAIN) 
        dosomethingelse();
      /// etc
      else {  
         syslog(LOG_DAEMON|LOG_ERR, "msgrcv failure with %s\n",
                strerror(errno)); 
         exit(EXIT_FAILURE); 
      };
    };
    

    Is the statement if (errno == ENOMSG) .... valid?

    Yes it is; you want to test errno only after some system call failure (e.g. when siz<0).

    Is there such a variable errno?

    Not any more. Please read carefully errno(3) documentation. You should not declare extern int errno; (this was possible in the 1980s, not in 21st century) but you should always #include and use errno as if it was a variable, but it is almost always some macro (whose definition appears in /usr/include/bits/errno.h which is included by /usr/include/errno.h).

    BTW, SysV-style facilities tend to become obsolete and are not always available. I recommend using POSIX message queues facilities, read mq_overview(7).

    You might want to read the freely downloadable Advanced Linux Programming (an old book; you can buy something better & newer) and/or all the man pages reachable from intro(2) & syscalls(2) & intro(3).

提交回复
热议问题