コード例 #1
0
ファイル: fishd.cpp プロジェクト: jay2013/fish-shell
/**
   Acquire the lock for the socket
   Returns the name of the lock file if successful or
   NULL if unable to obtain lock.
   The returned string must be free()d after unlink()ing the file to release
   the lock
*/
static bool acquire_socket_lock(const std::string &sock_name, std::string *out_lockfile_name)
{
    bool success = false;
    std::string lockfile;
    lockfile.reserve(sock_name.size() + strlen(LOCKPOSTFIX));
    lockfile = sock_name;
    lockfile.append(LOCKPOSTFIX);
    if (acquire_lock_file(lockfile, LOCKTIMEOUT, 1))
    {
        out_lockfile_name->swap(lockfile);
        success = true;
    }
    return success;
}
コード例 #2
0
ファイル: fishd.cpp プロジェクト: Soares/fish-shell
/**
   Acquire the lock for the socket
   Returns the name of the lock file if successful or 
   NULL if unable to obtain lock.
   The returned string must be free()d after unlink()ing the file to release 
   the lock
*/
static char *acquire_socket_lock( const char *sock_name )
{
	size_t len = strlen( sock_name );
	char *lockfile = (char *)malloc( len + strlen( LOCKPOSTFIX ) + 1 );
	
	if( lockfile == NULL ) 
	{
		wperror( L"acquire_socket_lock" );
		exit( EXIT_FAILURE );
	}
	strcpy( lockfile, sock_name );
	strcpy( lockfile + len, LOCKPOSTFIX );
	if ( !acquire_lock_file( lockfile, LOCKTIMEOUT, 1 ) )
	{
		free( lockfile );
		lockfile = NULL;
	}
	return lockfile;
}
コード例 #3
0
ファイル: daemon_utility.cpp プロジェクト: emwhbr/rpi
long become_daemon(const char *run_as_user,
		   const char *work_dir,
		   const char *lock_file,
		   int *fd_lock_file)
{
  pid_t pid;
  int fd;

  *fd_lock_file = DAEMON_BAD_FD_LOCK_FILE;

  // Switch to specified user
  if (run_as_user) {
    struct passwd *pw_info = getpwnam(run_as_user);
    if (pw_info) {
      if (setuid(pw_info->pw_uid) == -1) {
	syslog_error("setuid failed for %s, code=%d (%s)",
		     run_as_user, errno, strerror(errno));
	return DAEMON_FAILURE;
      }
    }
    else {
      syslog_error("getpwnam failed for %s", run_as_user);
      return DAEMON_FAILURE;
    }
  }

  // Step 1 : Create a child process
  pid = fork();
  switch (pid) {
  case -1 :
    syslog_error("fork(1) failed, code=%d (%s)", errno, strerror(errno));
    return DAEMON_FAILURE;
  case 0 :
    break;               // Child falls through
  default :
    exit(EXIT_SUCCESS);  // Parent terminates OK
  }

  // Step 2 : Become leader of new session
  if (setsid() == -1) {
    syslog_error("setsid failed, code=%d (%s)", errno, strerror(errno));
    return DAEMON_FAILURE;
  }

  // Step 3 : Ensure no controlling terminal
  pid = fork();
  switch (pid) {
  case -1 :
    syslog_error("fork(2) failed, code=%d (%s)", errno, strerror(errno));
    return DAEMON_FAILURE;
  case 0 :
    break;               // Grand-child falls through
  default :
    exit(EXIT_SUCCESS);  // Child terminates OK
  }

  // This process (grand-child) will be the actual daemon

  // Step 4 : Clear file mode creation mask
  umask(0);

  // Step 5 : Change current working directory
  if (chdir(work_dir) == -1) {
    syslog_error("chdir to '%s' failed, code=%d (%s)",
		 work_dir, errno, strerror(errno));
    return DAEMON_FAILURE;
  }

  // Step 6: Close standard file descriptors
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);

  // Step 7 : Redirect standard file descriptors to /dev/null
  fd = open("/dev/null", O_RDWR);
  if (fd != STDIN_FILENO) {
    syslog_error("Redirect STDIN failed, code=%d (%s)",
		 errno, strerror(errno));
    return DAEMON_FAILURE;
  }
  if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO) {
    syslog_error("Redirect STDOUT failed, code=%d (%s)",
		 errno, strerror(errno));
    return DAEMON_FAILURE;
  }
  if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) {
    syslog_error("Redirect STDERR failed, code=%d (%s)",
		 errno, strerror(errno));
    return DAEMON_FAILURE;
  }

  // Create lock file to prevent more than one instance
  // of the daemon is being executed
  if (lock_file) {
    if (acquire_lock_file(lock_file,
			  fd_lock_file) != DAEMON_SUCCESS) {
      return DAEMON_FAILURE;
    }
  }

  return DAEMON_SUCCESS;
}