common/pipe: add function to do pipe2(O_CLOEXEC)

Support old systems that don't have O_CLOEXEC.

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
This commit is contained in:
Colin Patrick McCabe 2011-08-22 10:48:15 -07:00
parent cf3b7cf6a9
commit abe5cd28d1
4 changed files with 84 additions and 5 deletions

View File

@ -817,6 +817,7 @@ libcommon_files = \
osd/osd_types.cc \
mds/MDSMap.cc \
common/common_init.cc \
common/pipe.c \
common/ceph_argparse.cc \
common/ceph_context.cc \
common/buffer.cc \
@ -1024,6 +1025,7 @@ noinst_HEADERS = \
global/global_init.h \
global/global_context.h \
common/common_init.h\
common/pipe.h\
common/code_environment.h \
common/signal.h\
global/signal_handler.h\

View File

@ -12,13 +12,14 @@
*
*/
#include "common/admin_socket.h"
#include "common/perf_counters.h"
#include "common/Thread.h"
#include "common/admin_socket.h"
#include "common/config.h"
#include "common/config_obs.h"
#include "common/dout.h"
#include "common/errno.h"
#include "common/perf_counters.h"
#include "common/pipe.h"
#include "common/safe_io.h"
#include <errno.h>
@ -110,11 +111,10 @@ public:
static std::string create_shutdown_pipe(int *pipe_rd, int *pipe_wr)
{
int pipefd[2];
int ret = pipe2(pipefd, O_CLOEXEC);
int ret = pipe_cloexec(pipefd);
if (ret < 0) {
int err = errno;
ostringstream oss;
oss << "AdminSocket::create_shutdown_pipe error: " << cpp_strerror(err);
oss << "AdminSocket::create_shutdown_pipe error: " << cpp_strerror(ret);
return oss.str();
}

44
src/common/pipe.c Normal file
View File

@ -0,0 +1,44 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2011 New Dream Network
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#include "common/pipe.h"
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
int pipe_cloexec(int pipefd[2])
{
#ifdef O_CLOEXEC
int ret;
ret = pipe2(pipefd, O_CLOEXEC);
if (ret) {
ret = -errno;
return ret;
}
return 0;
#else
/* The old-fashioned, race-condition prone way that we have to fall back on if
* O_CLOEXEC does not exist. */
int ret = pipe(pipefd);
if (ret) {
ret = -errno;
return ret;
}
fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
return 0;
#endif
}

33
src/common/pipe.h Normal file
View File

@ -0,0 +1,33 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2011 New Dream Network
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#ifndef CEPH_COMMON_PIPE_H
#define CEPH_COMMON_PIPE_H
#ifdef __cplusplus
extern "C" {
#endif
/** Create a pipe and set both ends to have F_CLOEXEC
*
* @param pipefd pipe array, just as in pipe(2)
* @return 0 on success, errno otherwise
*/
int pipe_cloexec(int pipefd[2]);
#ifdef __cplusplus
}
#endif
#endif