daemon 头文件_UNIX环境高级编程 ourhdr.h头文件 及其标准输出全程 myerror.c

在开始学习Stevens的《UNIX环境高级编程》的时候遇到一个问题,即是书中大量的例程用到了作者自己的头文件ourhdr.h,导致例程无法编译通过。这其实Stevens为了让例程更简洁而写的头文件和错误处理例程myerror.c,即书附录中的ourhdr.h,

err_xxx,log_xxx。

如下是书中Program

1.1例程ls.c。其中的err_quit()函数就是myerror.c中的函数,其头文件就定义ourhdr.h当中。我们在编译ls.c的时候必须将myerror.c列入gcc编译源文件,或者将myerror.c预先编译成库文件即

.a 文件,然后通过第三方函数库引入编译过程,即gcc提供的 -I -L选项。

#include

#include

#include "ourhdr.h"

int

main(int argc, char *argv[])

{

DIR *dp;

struct dirent *dirp;

if (argc != 2)

err_quit("a single argument (the directory name) is

required");

if ( (dp = opendir(argv[1])) == NULL)

err_sys("cat't open %s, argv[1]");

while ( (dirp = readdir(dp)) != NULL)

printf("%s\n", dirp->d_name);

closedir(dp);

exit(0);

}

这里介绍两种解决方法:

第1种,用gcc编译时加上myserror.c,也可用makefile编译程序

第2种,将myerror.c生成库文件libmy.a,每次编译时只需加个这个函数库。

第1种方案如图:

第2种方案其实就是预编译函数库的问题。在BBK小布老师GCC视频课程有详细介绍。这里就这个问题作个简单说明。

最初在编译myerror.c的时候遇到如下问题:

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o(.text+0x18):

In function `_start':

../sysdeps/i386/elf/start.S:77: undefined reference to `main'

collect2: ld returned 1 exit status

这是因为myerror.c文件中没有main函数,只有一系列的错误处理函数,所以编译时不能通过。

解决步骤:

1.生成目标文件:$gcc -Wall -c

myerror.c 生成myerror.o

2.生成库文件: $ar cr libmy.a

myerror.o 生成libmy.a,这里可以将多个.o文件放在后面做成一个库

3.编译ls.c: $gcc -Wall ls.c

libmy.a 生成a.out可以执行文件

以下方法和贴出源文件均在虚拟机Reahat

9.0上实验通过,过程如下:

ourhdr.h, myerror.c(加粗,红色)如下:

#ifndef __ourhdr_h

#define __ourhdr_h

#include 

#include 

#include 

#include 

#include 

#define MAXLINE 4096 #define

FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

#define

DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)

typedef void Sigfunc (int);

#if defined(SIG_IGN) &&

!defined(SIG_ERR)

#define SIG_ERR ((Sigfunc *)-1)

#endif

#define

min(a,b) ((a) < (b) ? (a) : (b))

#define

max(a,b) ((a) > (b) ? (a) : (b))

char *path_alloc (int *);

int open_max (void); void clr_fl (int, int); void set_fl (int, int); void pr_exit (int); void pr_mask (const char *);

Sigfunc *signal_intr (int, Sigfunc *);

int tty_cbreak (int); int tty_raw (int); int tty_reset (int); void tty_atexit

(void);

#ifdef ECHO struct termios *tty_termios (void);

#endif

void sleep_us (unsigned int);

ssize_t readn (int, void *, size_t);

ssize_t writen (int, const void *, size_t);

int daemon_init (void); int s_pipe (int *); int recv_fd (int, ssize_t (*func) (int, const void *,

size_t));

int send_fd (int, int); int send_err (int, int, const char *);

int serv_listen (const char *);

int serv_accept (int, uid_t *);

int cli_conn (const char *);

int buf_args (char *, int (*func) (int, char **));

int ptym_open (char *); int ptys_open (int, char *);

#ifdef TIOCGWINSZ

pid_t pty_fork (int *, char *, const struct termios *, const struct

winsize *);

#endif

int lock_reg (int, int, int, off_t, int, off_t);

#define read_lock(fd, offset, whence, len) \

lock_reg (fd, F_SETLK,

F_RDLCK, offset, whence, len)

#define readw_lock(fd, offset, whence, len) \

lock_reg (fd, F_SETLKW,

F_RDLCK, offset, whence, len)

#define write_lock(fd, offset, whence, len) \

lock_reg (fd, F_SETLK,

F_WRLCK, offset, whence, len)

#define writew_lock(fd, offset, whence, len) \

lock_reg (fd, F_SETLKW,

F_WRLCK, offset, whence, len)

#define un_lock(fd, offset, whence, len) \

lock_reg (fd, F_SETLK,

F_UNLCK, offset, whence, len)

pid_t lock_test (int, int, off_t, int, off_t);

#define is_readlock(fd, offset, whence, len) \

lock_test (fd, F_RDLCK,

offset, whence, len)

#define is_writelock(fd, offset, whence, len) \

lock_test (fd, F_WRLCK, offset, whence, len)

void err_dump (const char *, ...);

void err_msg (const char *, ...);

void err_quit (const char *, ...);

void err_ret (const char *, ...);

void err_sys (const char *, ...);

void log_msg (const char *, ...);

void log_open (const char *, int, int);

void log_quit (const char *, ...);

void log_ret (const char *, ...);

void log_sys (const char *, ...);

void TELL_WAIT (void); void TELL_PARENT (pid_t);

void TELL_CHILD (pid_t);

void WAIT_PARENT (void);

void WAIT_CHILD (void);

#endif

#include

 #include

 #include "ourhdr.h" static void err_doit(int, const char *,

va_list); char *pname =

NULL; void err_ret(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, fmt, ap); va_end(ap); return; } void err_sys(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, fmt, ap); va_end(ap); exit(1); } void err_dump(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, fmt, ap); va_end(ap); abort(); exit(1); } void err_msg(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(0, fmt, ap); va_end(ap); return; } void err_quit(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(0, fmt, ap); va_end(ap); exit(1); } static void err_doit(int errnoflag, const char *fmt, va_list

ap) { int errno_save; char buf[MAXLINE]; errno_save =

errno; vsprintf(buf, fmt, ap); if (errnoflag) sprintf

(buf+strlen(buf), ": %s", strerror

(errno_save)); strcat (buf, "\n"); fflush(stdout); fputs(buf, stderr); fflush(NULL);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值