barrier/src/lib/arch/unix/ArchDaemonUnix.cpp
Peter Hutterer 0dbedd31dc Remove trailing whitespaces
Many tools strip trailing whitespaces by default, so after editing a file with
whitespace errors we end up with a bunch of unrelated hunks that need to be
reverted locally.

This could be fixed by configuring each tool to not do this (at least for the
barrier repo), or, simpler, we just sed the problem away and make barrier
whitespace-compliant.

sed commands run:
    sed -i 's/[ \t]\+$//' **/*.(cpp|h) **/*CMakeLists.txt

Verified with git diff --ignore-space-change, this shows the empty diff.
2020-12-09 14:02:28 +10:00

133 lines
3.1 KiB
C++

/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arch/unix/ArchDaemonUnix.h"
#include "arch/unix/XArchUnix.h"
#include "base/Log.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <cstdlib>
//
// ArchDaemonUnix
//
ArchDaemonUnix::ArchDaemonUnix()
{
// do nothing
}
ArchDaemonUnix::~ArchDaemonUnix()
{
// do nothing
}
#ifdef __APPLE__
// In Mac OS X, fork()'d child processes can't use most APIs (the frameworks
// that Barrier uses in fact prevent it and make the process just up and die),
// so need to exec a copy of the program that doesn't fork so isn't limited.
int
execSelfNonDaemonized()
{
extern char** NXArgv;
char** selfArgv = NXArgv;
setenv("_BARRIER_DAEMONIZED", "", 1);
execvp(selfArgv[0], selfArgv);
return 0;
}
bool alreadyDaemonized() {
return std::getenv("_BARRIER_DAEMONIZED") != NULL;
}
#endif
int
ArchDaemonUnix::daemonize(const char* name, DaemonFunc func)
{
#ifdef __APPLE__
if (alreadyDaemonized())
return func(1, &name);
#endif
// fork so shell thinks we're done and so we're not a process
// group leader
switch (fork()) {
case -1:
// failed
throw XArchDaemonFailed(new XArchEvalUnix(errno));
case 0:
// child
break;
default:
// parent exits
exit(0);
}
// become leader of a new session
setsid();
#ifndef __APPLE__
// NB: don't run chdir on apple; causes strange behaviour.
// chdir to root so we don't keep mounted filesystems points busy
// TODO: this is a bit of a hack - can we find a better solution?
int chdirErr = chdir("/");
if (chdirErr)
// NB: file logging actually isn't working at this point!
LOG((CLOG_ERR "chdir error: %i", chdirErr));
#endif
// mask off permissions for any but owner
umask(077);
// close open files. we only expect stdin, stdout, stderr to be open.
close(0);
close(1);
close(2);
// attach file descriptors 0, 1, 2 to /dev/null so inadvertent use
// of standard I/O safely goes in the bit bucket.
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
int dupErr = dup(1);
if (dupErr < 0) {
// NB: file logging actually isn't working at this point!
LOG((CLOG_ERR "dup error: %i", dupErr));
}
#ifdef __APPLE__
return execSelfNonDaemonized();
#endif
// invoke function
return func(1, &name);
}