函数err_sys()定义在哪里?

13

在这段代码中,我遇到了一个与err_sys()相关的错误:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
    int sockfd;

    if ((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
        err_sys("can't create socket");

    close(sockfd);
    return 0;
}

我正在遇到连接器错误:
/tmp/cciuUVhz.o: In function `main':
getsockopt.c:(.text+0x38): undefined reference to `err_sys'
collect2: ld returned 1 exit status
< p >函数err_sys()定义在哪里?< /p >

3
没有听说过“err_sys”(所以我不知道“getsockopt.cpp”如何编译)。请使用“perror”或“strerror”。另外,请确实接受一些之前的答案。这并不难! - Lightness Races in Orbit
@Tomalak: 它可能会编译成功,因为警告级别不够高,而C标准允许您不声明函数的原型。 - Oliver Charlesworth
@Oli:真的吗?我不用C,所以我不知道。那太可怕了!(这让我想起来...当然我上面是指getsockopt.c - Lightness Races in Orbit
@Tomalak: 的确如此!这很严峻。例如,可以在这里查看被接受的答案:https://dev59.com/63E85IYBdhLWcg3w3Xdp。 - Oliver Charlesworth
7个回答

27

将此代码放在你的代码顶部:

void err_sys(const char* x) 
{ 
    perror(x); 
    exit(1); 
}

perror在stdio.h中定义。

err_sys在Richard Stevens的书“UNIX网络编程:套接字网络API”中使用。据我所知,这不是常见的东西。

编辑:已修正代码错误。


2
为什么不使用函数来实现这个,而不是宏? - Oliver Charlesworth
5
写成这样的宏存在严重的错误,例如 if (foo) err_sys(x); else ... 会失败。如果你无法编写正确的宏,请使用函数! - R.. GitHub STOP HELPING ICE
4
要将其编写为宏,您需要#define err_sys(x) do { perror(x); exit(1); } while (0)。这不会违反if (foo) err_sys(x); else ...问题。“do {...} while (0)”是一种标准技术,不会出现错误。 - Jonathan Leffler

7

这是来自《TCP/IP Illustrated》吗?我记得在附录中提供了定义:

#include <errno.h>
#include <stdarg.h>
/*
 * Print a message and return to caller.
 * Caller specifies "errnoflag".
 */
static void
err_doit(int errnoflag, int error, const char *fmt, va_list ap)
{
    char    buf[MAXLINE];
    vsnprintf(buf, MAXLINE, fmt, ap);
    if (errnoflag)
        snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s",
    strerror(error));
    strcat(buf, "\n");
    fflush(stdout);     /* in case stdout and stderr are the same */
    fputs(buf, stderr);
    fflush(NULL);       /* flushes all stdio output streams */
}


/*
 * Fatal error related to a system call.
 * Print a message and terminate.
 */
void
err_sys(const char *fmt, ...)
{
    va_list     ap;
    va_start(ap, fmt);
    err_doit(1, errno, fmt, ap);
    va_end(ap);
    exit(1);
}

3

err_sys()是由W. Richard Stevens编写的几本书中使用的函数。该函数用于打印发生了什么类型的错误。

该函数在文本中的程序中使用自定义头文件"ourhdr.h"(或其他文件)中。请参阅附录以获取标头列表或函数定义。


2

这个函数的源代码(来自W. Richard Stevens的《UNIX®环境高级编程》)可以在该书网站上找到:http://www.apuebook.com/


1

请下载本书的源代码文件夹,您可以在以下链接中找到它: http://www.unpbook.com/src.html

打开源代码文件夹并选择lib文件夹。接下来打开名为error.c的文件。您将在其中找到定义了sys_err()的内容。


1

您需要指定包含此函数实现的库文件。这是编译C代码时常见的问题。


3
当你使用一个没有实现的函数时,这种情况尤其普遍,因为该函数并不存在。 - Lightness Races in Orbit

1

正如其他人所说,这段代码看起来像是Stevens的例子:Unix网络编程。如果你有这本书,可以查看附录D:教材定义的各种源代码(以及在示例中广泛使用的unp.h头文件)。这个文件太长了,无法在SO答案中输入,但是快速搜索Stevens的“标准错误函数”会返回很多带有实现的谷歌图书结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接