From 3ff53df7b4cbc331d302181d2d6644f4cb860a52 Mon Sep 17 00:00:00 2001 From: Paul Tan Date: Tue, 4 Aug 2015 21:51:22 +0800 Subject: wrapper: implement xopen() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A common usage pattern of open() is to check if it was successful, and die() if it was not: int fd = open(path, O_WRONLY | O_CREAT, 0777); if (fd < 0) die_errno(_("Could not open '%s' for writing."), path); Implement a wrapper function xopen() that does the above so that we can save a few lines of code, and make the die() messages consistent. Helped-by: Torsten Bögershausen Helped-by: Jeff King Helped-by: Johannes Schindelin Helped-by: Junio C Hamano Signed-off-by: Paul Tan Signed-off-by: Junio C Hamano --- wrapper.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'wrapper.c') diff --git a/wrapper.c b/wrapper.c index ff49807948..0a4502d232 100644 --- a/wrapper.c +++ b/wrapper.c @@ -189,6 +189,41 @@ void *xcalloc(size_t nmemb, size_t size) # endif #endif +/** + * xopen() is the same as open(), but it die()s if the open() fails. + */ +int xopen(const char *path, int oflag, ...) +{ + mode_t mode = 0; + va_list ap; + + /* + * va_arg() will have undefined behavior if the specified type is not + * compatible with the argument type. Since integers are promoted to + * ints, we fetch the next argument as an int, and then cast it to a + * mode_t to avoid undefined behavior. + */ + va_start(ap, oflag); + if (oflag & O_CREAT) + mode = va_arg(ap, int); + va_end(ap); + + for (;;) { + int fd = open(path, oflag, mode); + if (fd >= 0) + return fd; + if (errno == EINTR) + continue; + + if ((oflag & O_RDWR) == O_RDWR) + die_errno(_("could not open '%s' for reading and writing"), path); + else if ((oflag & O_WRONLY) == O_WRONLY) + die_errno(_("could not open '%s' for writing"), path); + else + die_errno(_("could not open '%s' for reading"), path); + } +} + /* * xread() is the same a read(), but it automatically restarts read() * operations with a recoverable error (EAGAIN and EINTR). xread() -- cgit v1.2.1