Postfix3.3.1
全て データ構造 ファイル 関数 変数 型定義 マクロ定義
fifo_listen.c
[詳解]
1 /*++
2 /* NAME
3 /* fifo_listen 3
4 /* SUMMARY
5 /* start fifo listener
6 /* SYNOPSIS
7 /* #include <listen.h>
8 /*
9 /* int fifo_listen(path, permissions, block_mode)
10 /* const char *path;
11 /* int permissions;
12 /* int block_mode;
13 /* DESCRIPTION
14 /* The \fBfifo_listen\fR routine creates the specified named pipe with
15 /* the specified permissions, opens the FIFO read-write or read-only,
16 /* depending on the host operating system, and returns the resulting
17 /* file descriptor.
18 /* The \fIblock_mode\fR argument is either NON_BLOCKING for
19 /* a non-blocking socket, or BLOCKING for blocking mode.
20 /* DIAGNOSTICS
21 /* Fatal errors: all system call failures.
22 /* LICENSE
23 /* .ad
24 /* .fi
25 /* The Secure Mailer license must be distributed with this software.
26 /* AUTHOR(S)
27 /* Wietse Venema
28 /* IBM T.J. Watson Research
29 /* P.O. Box 704
30 /* Yorktown Heights, NY 10598, USA
31 /*--*/
32 
33 /* System interfaces. */
34 
35 #include <sys_defs.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 
41 /* Utility library. */
42 
43 #include "msg.h"
44 #include "iostuff.h"
45 #include "listen.h"
46 #include "warn_stat.h"
47 
48 #define BUF_LEN 100
49 
50 /* fifo_listen - create fifo listener */
51 
52 int fifo_listen(const char *path, int permissions, int block_mode)
53 {
54  char buf[BUF_LEN];
55  static int open_mode = 0;
56  const char *myname = "fifo_listen";
57  struct stat st;
58  int fd;
59  int count;
60 
61  /*
62  * Create a named pipe (fifo). Do whatever we can so we don't run into
63  * trouble when this process is restarted after crash. Make sure that we
64  * open a fifo and not something else, then change permissions to what we
65  * wanted them to be, because mkfifo() is subject to umask settings.
66  * Instead we could zero the umask temporarily before creating the FIFO,
67  * but that would cost even more system calls. Figure out if the fifo
68  * needs to be opened O_RDWR or O_RDONLY. Some systems need one, some
69  * need the other. If we choose the wrong mode, the fifo will stay
70  * readable, causing the program to go into a loop.
71  */
72  if (unlink(path) && errno != ENOENT)
73  msg_fatal("%s: remove %s: %m", myname, path);
74  if (mkfifo(path, permissions) < 0)
75  msg_fatal("%s: create fifo %s: %m", myname, path);
76  switch (open_mode) {
77  case 0:
78  if ((fd = open(path, O_RDWR | O_NONBLOCK, 0)) < 0)
79  msg_fatal("%s: open %s: %m", myname, path);
80  if (readable(fd) == 0) {
81  open_mode = O_RDWR | O_NONBLOCK;
82  break;
83  } else {
84  open_mode = O_RDONLY | O_NONBLOCK;
85  if (msg_verbose)
86  msg_info("open O_RDWR makes fifo readable - trying O_RDONLY");
87  (void) close(fd);
88  /* FALLTRHOUGH */
89  }
90  default:
91  if ((fd = open(path, open_mode, 0)) < 0)
92  msg_fatal("%s: open %s: %m", myname, path);
93  break;
94  }
95 
96  /*
97  * Make sure we opened a FIFO and skip any cruft that might have
98  * accumulated before we opened it.
99  */
100  if (fstat(fd, &st) < 0)
101  msg_fatal("%s: fstat %s: %m", myname, path);
102  if (S_ISFIFO(st.st_mode) == 0)
103  msg_fatal("%s: not a fifo: %s", myname, path);
104  if (fchmod(fd, permissions) < 0)
105  msg_fatal("%s: fchmod %s: %m", myname, path);
106  non_blocking(fd, block_mode);
107  while ((count = peekfd(fd)) > 0
108  && read(fd, buf, BUF_LEN < count ? BUF_LEN : count) > 0)
109  /* void */ ;
110  return (fd);
111 }
int msg_verbose
Definition: msg.c:177
#define stat(p, s)
Definition: warn_stat.h:18
#define readable(fd)
Definition: iostuff.h:36
#define BUF_LEN
Definition: fifo_listen.c:48
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int fifo_listen(const char *path, int permissions, int block_mode)
Definition: fifo_listen.c:52
ssize_t peekfd(int)
Definition: peekfd.c:60
int non_blocking(int, int)
Definition: non_blocking.c:55
#define fstat(f, s)
Definition: warn_stat.h:20
void msg_info(const char *fmt,...)
Definition: msg.c:199