Skip to content

Instantly share code, notes, and snippets.

@jclulow
Created July 5, 2010 11:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jclulow/464265 to your computer and use it in GitHub Desktop.
Save jclulow/464265 to your computer and use it in GitHub Desktop.
Index: Makefile.in
===================================================================
--- Makefile.in (revision 2063)
+++ Makefile.in (working copy)
@@ -1,3 +1,5 @@
+SHELL := @MAKE_SHELL@
+
# Support out-of-tree builds
srcdir := @srcdir@
VPATH := @srcdir@
@@ -13,6 +15,7 @@
sbindir := @sbindir@
localstatedir := @localstatedir@
CXX := @CXX@
+INSTALL := @INSTALL@
CXXFLAGS := @CPPFLAGS@ @CXXFLAGS@
LDFLAGS := @LDFLAGS@
LIBS := @LIBS@
@@ -75,15 +78,15 @@
mkdir -p $(DESTDIR)$(MODDIR)
mkdir -p $(DESTDIR)$(DATADIR)
cp -Rp $(srcdir)/webskins $(DESTDIR)$(DATADIR)
- install -m 0755 znc $(DESTDIR)$(bindir)
- install -m 0755 znc-config $(DESTDIR)$(bindir)
- install -m 0755 znc-buildmod $(DESTDIR)$(bindir)
- install -m 0644 $(srcdir)/*.h $(DESTDIR)$(includedir)/znc
- install -m 0644 znc.pc $(DESTDIR)$(PKGCONFIGDIR)
+ $(INSTALL) -m 0755 znc $(DESTDIR)$(bindir)
+ $(INSTALL) -m 0755 znc-config $(DESTDIR)$(bindir)
+ $(INSTALL) -m 0755 znc-buildmod $(DESTDIR)$(bindir)
+ $(INSTALL) -m 0644 $(srcdir)/*.h $(DESTDIR)$(includedir)/znc
+ $(INSTALL) -m 0644 znc.pc $(DESTDIR)$(PKGCONFIGDIR)
@$(MAKE) -C modules install DESTDIR=$(DESTDIR);
if test -n "$(LIBZNC)"; then \
mkdir -p $(DESTDIR)$(LIBZNCDIR) || exit 1 ; \
- install -m 0755 $(LIBZNC) $(DESTDIR)$(LIBZNCDIR) || exit 1 ; \
+ $(INSTALL) -m 0755 $(LIBZNC) $(DESTDIR)$(LIBZNCDIR) || exit 1 ; \
fi
@$(MAKE) -C man install DESTDIR=$(DESTDIR)
Index: AUTHORS
===================================================================
--- AUTHORS (revision 2063)
+++ AUTHORS (working copy)
@@ -28,3 +28,4 @@
Reed Loden <reed@reedloden.com>
Brian Campbell (bcampbell@splafinga.com)
Alexey "DarthGandalf" Sokolov (http://asokolov.co.cc/)
+Joshua M. Clulow (http://sysmgr.org)
Index: modules/Makefile.in
===================================================================
--- modules/Makefile.in (revision 2063)
+++ modules/Makefile.in (working copy)
@@ -1,3 +1,5 @@
+SHELL := @MAKE_SHELL@
+
# Support out-of-tree builds
srcdir := @srcdir@
VPATH := @srcdir@
@@ -12,6 +14,7 @@
sbindir := @sbindir@
localstatedir := @localstatedir@
CXX := @CXX@
+INSTALL := @INSTALL@
# CXXFLAGS are for the main binary, so don't use them here, use MODFLAGS instead
MODFLAGS := @CPPFLAGS@ @MODFLAGS@ -I$(srcdir)/..
MODLINK := @MODLINK@
@@ -84,7 +87,7 @@
all: $(TARGETS)
install: all create_install_dir install_metadirs $(PERLHOOK) $(TCLHOOK)
- install -m 0755 $(TARGETS) $(DESTDIR)$(MODDIR)
+ $(INSTALL) -m 0755 $(TARGETS) $(DESTDIR)$(MODDIR)
create_install_dir:
mkdir -p $(DESTDIR)$(MODDIR)
@@ -109,12 +112,12 @@
modperl_install: create_install_dir
for i in $(srcdir)/*.pm; do \
- install -m 0644 $$i $(DESTDIR)$(MODDIR); \
+ $(INSTALL) -m 0644 $$i $(DESTDIR)$(MODDIR); \
done
modtcl_install:
mkdir -p $(DESTDIR)$(DATADIR)/modtcl/
- install -m 0644 $(srcdir)/extra/modtcl.tcl $(srcdir)/extra/binds.tcl $(DESTDIR)$(DATADIR)/modtcl/
+ $(INSTALL) -m 0644 $(srcdir)/extra/modtcl.tcl $(srcdir)/extra/binds.tcl $(DESTDIR)$(DATADIR)/modtcl/
uninstall:
# Yes, we are lazy, just remove everything in there
Index: man/Makefile.in
===================================================================
--- man/Makefile.in (revision 2063)
+++ man/Makefile.in (working copy)
@@ -1,3 +1,5 @@
+SHELL := @MAKE_SHELL@
+
# Support out-of-tree builds
VPATH := @srcdir@
@@ -8,6 +10,8 @@
MAN1 := znc.1.gz znc-buildmod.1.gz znc-config.1.gz
+INSTALL := @INSTALL@
+
all: $(MAN1)
%.1.gz: %.1 Makefile
@@ -18,7 +22,7 @@
install: $(MAN1)
mkdir -p $(DESTDIR)$(mandir)/man1
- install -m 644 $(MAN1) $(DESTDIR)$(mandir)/man1
+ $(INSTALL) -m 644 $(MAN1) $(DESTDIR)$(mandir)/man1
uninstall:
for file in $(MAN1) ; do \
Index: znc.h
===================================================================
--- znc.h (revision 2063)
+++ znc.h (working copy)
@@ -38,6 +38,7 @@
void ReleaseISpoof();
bool WritePidFile(int iPid);
bool DeletePidFile();
+ bool WaitForChildLock();
Csock* FindSockByName(const CString& sSockName);
bool IsHostAllowed(const CString& sHostMask) const;
// This returns false if there are too many anonymous connections from this ip
Index: configure.in
===================================================================
--- configure.in (revision 2063)
+++ configure.in (working copy)
@@ -53,6 +53,9 @@
appendCXX "-D_FORTIFY_SOURCE=2"
+INSTALL=install
+MAKE_SHELL=/bin/sh
+
case "${host_os}" in
freebsd*)
# -D__GNU_LIBRARY__ makes this work on fbsd 4.11
@@ -62,6 +65,9 @@
;;
solaris*)
appendLib -lsocket -lnsl
+ appendCXX -DNO_FLOCK
+ INSTALL=/usr/ucb/install
+ MAKE_SHELL=/usr/bin/ksh
ISSUN=1
;;
cygwin)
@@ -356,6 +362,8 @@
appendCXX "-D_MODDIR_=\\\"${MODDIR}\\\""
appendCXX "-D_DATADIR_=\\\"${DATADIR}\\\""
+AC_SUBST([INSTALL])
+AC_SUBST([MAKE_SHELL])
AC_SUBST([CXXFLAGS])
AC_SUBST([CPPFLAGS])
AC_SUBST([MODFLAGS])
Index: configure
===================================================================
--- configure (revision 2063)
+++ configure (working copy)
@@ -568,6 +568,8 @@
LIBZNCDIR
LIBZNC
MODFLAGS
+MAKE_SHELL
+INSTALL
PERL_BINARY
openssl_LIBS
openssl_CFLAGS
@@ -2753,6 +2755,9 @@
appendCXX "-D_FORTIFY_SOURCE=2"
+INSTALL=install
+MAKE_SHELL=/bin/sh
+
case "${host_os}" in
freebsd*)
# -D__GNU_LIBRARY__ makes this work on fbsd 4.11
@@ -2762,6 +2767,9 @@
;;
solaris*)
appendLib -lsocket -lnsl
+ appendCXX -DNO_FLOCK
+ INSTALL=/usr/ucb/install
+ MAKE_SHELL=/usr/bin/ksh
ISSUN=1
;;
cygwin)
@@ -3883,6 +3891,8 @@
+
+
ac_config_files="$ac_config_files Makefile"
ac_config_files="$ac_config_files znc-config"
Index: FileUtils.cpp
===================================================================
--- FileUtils.cpp (revision 2063)
+++ FileUtils.cpp (working copy)
@@ -21,6 +21,16 @@
# define O_BINARY 0
#endif
+#ifdef NO_FLOCK
+/*
+ * flock operations.
+ */
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* don't block when locking */
+#define LOCK_UN 8 /* unlock */
+#endif
+
CFile::CFile() {
m_iFD = -1;
}
@@ -391,18 +401,61 @@
return Lock(LOCK_EX|LOCK_NB);
}
+bool CFile::WaitForExLock() {
+ return Lock(LOCK_EX);
+}
+
bool CFile::UnLock() {
return Lock(LOCK_UN);
}
bool CFile::Lock(int iOperation) {
+#ifdef NO_FLOCK
+ struct flock fl;
+ int ret;
+ int cmd;
+#endif
+
if (m_iFD == -1) {
return false;
}
+#ifdef NO_FLOCK
+ /* Solaris 9 & 10+ do not have a 'useful' flock() ... */
+ bzero(&fl, sizeof(fl));
+ if (iOperation & LOCK_NB) {
+ cmd = F_SETLK;
+ iOperation &= ~LOCK_NB; /* turn off this bit */
+ } else {
+ cmd = F_SETLKW;
+ }
+ switch (iOperation) {
+ case LOCK_UN:
+ fl.l_type |= F_UNLCK;
+ break;
+ case LOCK_SH:
+ fl.l_type |= F_RDLCK;
+ break;
+ case LOCK_EX:
+ fl.l_type |= F_WRLCK;
+ break;
+ default:
+ errno = EINVAL;
+ return false;
+ }
+ ret = fcntl(m_iFD, cmd, &fl);
+ if (ret == -1) {
+ /* if LOCK_NB was used and we might have blocked, then
+ set errno to 'expected' value */
+ if (cmd == F_SETLK && (errno == EACCES || errno == EAGAIN))
+ errno = EWOULDBLOCK;
+ return false;
+ }
+#else
if (flock(m_iFD, iOperation) != 0) {
return false;
}
+#endif /* NO_FLOCK */
return true;
}
Index: main.cpp
===================================================================
--- main.cpp (revision 2063)
+++ main.cpp (working copy)
@@ -254,6 +254,17 @@
return 0;
}
+#ifdef NO_FLOCK
+ /* fcntl() locks don't necessarily propagate to forked()
+ * children. Reacquire the lock here. Use the blocking
+ * call to avoid race condition with parent exiting. */
+ if (!pZNC->WaitForChildLock()) {
+ CUtils::PrintError("Child was unable to obtain lock on config file.");
+ delete pZNC;
+ return 1;
+ }
+#endif
+
// Redirect std in/out/err to /dev/null
close(0); open("/dev/null", O_RDONLY);
close(1); open("/dev/null", O_WRONLY);
Index: FileUtils.h
===================================================================
--- FileUtils.h (revision 2063)
+++ FileUtils.h (working copy)
@@ -111,6 +111,7 @@
bool TryExLock(const CString& sLockFile, int iFlags = O_RDONLY | O_CREAT);
bool TryExLock();
+ bool WaitForExLock();
bool UnLock();
bool IsOpen() const;
Index: znc.cpp
===================================================================
--- znc.cpp (revision 2063)
+++ znc.cpp (working copy)
@@ -1058,7 +1058,9 @@
if (m_LockFile.IsOpen())
m_LockFile.Close();
- if (!m_LockFile.Open(m_sConfigFile)) {
+ /* need to open the config file Read/Write for fcntl()
+ * exclusive locking to work properly: */
+ if (!m_LockFile.Open(m_sConfigFile, O_RDWR)) {
sError = "Can not open config file";
CUtils::PrintStatus(false, sError);
return false;
@@ -2071,3 +2073,8 @@
if (m_pConnectUserTimer == pTimer)
m_pConnectUserTimer = NULL;
}
+
+bool CZNC::WaitForChildLock() {
+ return m_LockFile.WaitForExLock();
+}
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment