Esempio n. 1
0
/* translate elf EF_ defines -- tricky as it's based on EM_ */
static unsigned int get_eflags(elfobj *elf)
{
	if (elf->elf_class == ELFCLASS32)
		return EGET(EHDR32(elf->ehdr)->e_flags);
	else
		return EGET(EHDR64(elf->ehdr)->e_flags);
}
Esempio n. 2
0
unsigned int get_etype(elfobj *elf)
{
	if (elf->elf_class == ELFCLASS32)
		return EGET(EHDR32(elf->ehdr)->e_type);
	else
		return EGET(EHDR64(elf->ehdr)->e_type);
}
Esempio n. 3
0
int Process::parseStatus(int result, int status)
{
  logTrace("Process::parseStatus");

  if (result > 0)
  {
    if (WIFSTOPPED(status))
    {
      logTest("Process::parseStatus", "Child %d was stopped "
                  "with signal %d", pid_, (WSTOPSIG(status)));
    }
    else
    {
      #ifdef TEST

      if (WIFEXITED(status))
      {
        logTest("Process::parseStatus", "Child %d exited "
                    "with status %d", pid_, (WEXITSTATUS(status)));
      }
      else if (WIFSIGNALED(status))
      {
        logTest("Process::parseStatus", "Child %d died "
                    "because of signal %d", pid_, (WTERMSIG(status)));
      }

      #endif

      status_ = status;

      return 1;
    }
  }
  else if (result < 0)
  {
    if (EGET() == ECHILD)
    {
      //
      // The process died but we missed to
      // call the waitpid() at the time.
      //

      logWarning("Process::parseStatus::waitpid", EGET());

      return 1;
    }

    logError("Process::parseStatus::waitpid", EGET());

    return -1;
  }

  return 0;
}
Esempio n. 4
0
int Process::kill(int signal)
{
  logTrace("Process::kill");

  logTest("Process::kill", "Sending signal %d to process %d",
              signal, pid_);

  if (::kill(pid_, signal) < 0 && EGET() != ESRCH)
  {
    logError("Process::kill::kill", EGET());

    return -1;
  }

  return 1;
}
Esempio n. 5
0
static int
TRANS(DNETGetPeerAddr) (XtransConnInfo ciptr)

{
    struct sockaddr_dn	sockname;
    int			namelen = sizeof(sockname);

    PRMSG (3,"DNETGetPeerAddr(%x)\n", ciptr, 0, 0);

    if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
    {
	PRMSG (1,"DNETGetPeerAddr: getpeername() failed: %d\n",
	      EGET(), 0, 0);
	return -1;
    }

    /*
     * Everything looks good: fill in the XtransConnInfo structure.
     */

    if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
    {
        PRMSG (1,
	      "DNETGetPeerAddr: Can't allocate space for the addr\n",
	      0, 0, 0);
        return -1;
    }

    ciptr->peeraddrlen = namelen;
    memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);

    return 0;
}
Esempio n. 6
0
int Process::wait(const T_timestamp timeout)
{
  logTrace("Process::wait");

  if (pid_ < 0)
  {
    logError("Process::wait", ESET(ECHILD));

    return 1;
  }

  //
  // Wait for the process until the timeout.
  //

  int status;

  int options = WUNTRACED;

  setTimer(timeout);

  int result;

  if ((result = waitpid(pid_, &status, options)) == -1)
  {
    if (EGET() == EINTR)
    {
      logTest("Process::wait", "Timeout raised waiting "
                  "for pid %d", pid_);

      return 0;
    }
    else
    {
      logError("Process::wait", EGET());

      return -1;      
    }
  }

  resetTimer();

  result = parseStatus(result, status);

  return result;
}
Esempio n. 7
0
File: at_new.c Progetto: piki/gat
static gboolean prepare_last_page(GnomeDruidPageEdge *pg, GtkWidget *ign,
    at_druid_info *info) {
  char *desc;
  const char *cmd = EGET(command);
  guint month, day, year;
  if (!cmd || !*cmd) {
    gnome_druid_page_edge_set_text(pg,
      "No command set.  Click \"Back\" to set one.");
    return TRUE;
  }
  gtk_calendar_get_date(GTK_CALENDAR(info->cal), &year, &month, &day);
  desc = g_strdup_printf("When: %02d/%02d/%04d at %02d:%02d\nWhat: %s\n\n"
    "If this is correct, click \"Apply\"", month+1, day, year,
    SGET(hour), SGET(minute), EGET(command));
  gnome_druid_page_edge_set_text(pg, desc);
  g_free(desc);
  return TRUE;
}
Esempio n. 8
0
int Service::logCheck(const char *file, const char *search)
{
  FILE *fp;
  char line[DEFAULT_STRING_LENGTH];
  int found;

  if (file == NULL)
  {
    #ifdef WARNING
    logUser("Service::logCheck: WARNING! No file specified.");
    #endif

    return 0;
  }

  fp = fopen(file, "r");

  if (fp == NULL)
  {
    #ifdef WARNING
    logUser("Service::logCheck: WARNING! Cannot open the file: (error %d) %s", EGET(), ESTR());
    #endif

    return 0;
  }

  //
  // TODO: This function could be optimized using
  // the search stream direction.
  //

  found = 0;

  while (!feof(fp))
  {
    fgets(line, DEFAULT_STRING_LENGTH-1, fp);

    #ifdef TEST
    logUser("Service::logCheck: Going to examine line [%s].", line);
    #endif

    if (strstr(line, search) != NULL)
    {
      found = 1;
      break;
    }
  }

  fclose(fp);

  return (found);
}
Esempio n. 9
0
FILE *Process::setDescriptorStream(int &fd, FILE *&stream, char *mode)
{
  logTrace("Process::setDescriptorStream");

  if ((stream = fdopen(fd, mode)) == NULL)
  {
    logError("Process::setDescriptorStream::fdopen", EGET());

    logTest("Process::setDescriptorStream", "Can't create "
                "stream for descriptor %d", fd);

    return getNullStream();
  }

  return stream;
}
Esempio n. 10
0
File: at_new.c Progetto: piki/gat
static gboolean at_commit_job(at_druid_info *info) {
  const char *t;
  guint month, day, year;
  at_job_t *job = NULL;
  t = EGET(command);
  if (!t || !*t) return FALSE;
  job = g_new(at_job_t, 1);
  job->cmd = strdup(t);
  job->id = job->queue = job->when = NULL;

  gtk_calendar_get_date(GTK_CALENDAR(info->cal), &year, &month, &day);
  job->when = g_strdup_printf("%02d%02d %02d/%02d/%04d",
    SGET(hour), SGET(minute), month+1, day, year);

  gtk_widget_destroy(info->win);
  at_add_job(job);
  return TRUE;
}
Esempio n. 11
0
int Process::waitFork()
{
  int limit   = RETRY_FORK_LIMIT;
  int timeout = RETRY_FORK_INTERVAL;

  int pid;

  for (int i = 0; i < limit; i++)
  {
    logTest("Process::waitFork", "Trying at %s",
                strMsTimestamp());

    //
    // It could optionally try again only if the
    // error code is 11, 'Resource temporarily
    // unavailable'.
    //

    if ((pid = fork()) >= 0)
    {
      break;
    }
    else if (i < limit - 1)
    {
      logTest("Process::waitFork::fork", "Function "
                     "fork failed");

      logError("Process::waitFork::fork", EGET());


      logTest("Process::waitFork", "Trying again");

      usleep(timeout * 1000);
    }
  }

  if (pid <= 0)
  {
    logTest("Process::waitFork", "Returning at %s",
                strMsTimestamp());
  }

  return pid;
}
Esempio n. 12
0
FILE *Process::getNullStream()
{
  logTrace("Process::getNullStream");

  if (nullStream_ == NULL)
  {
    logTest("Process::getNullStream", "Creating a "
                "fake stream as '%s'", nullStreamName_);

    if ((nullStream_ = fopen(nullStreamName_, "a+")) == NULL)
    {
      logError("Process::getNullStream::fopen", EGET());

      logTest("Process::getNullStream", "Can't create "
                  "a fake stream as '%s'", nullStreamName_);
    }
  }

  return nullStream_;
}
Esempio n. 13
0
int Keeper::collect(const char *path)
{
  #ifdef TEST
  *logofs << "Keeper: Looking for files in directory '"
          << path << "'.\n" << logofs_flush;
  #endif

  DIR *cacheDir = opendir(path);

  if (cacheDir != NULL)
  {
    File *file;

    dirent *dirEntry;

    struct stat fileStat;

    int baseSize = strlen(path);
    int fileSize = baseSize + 3 + MD5_LENGTH * 2 + 1;

    int n = 0;
    int s = 0;

    while (((dirEntry = readdir(cacheDir)) != NULL))
    {
      if (s++ % ONCE == 0) usleep(sleep_ * 1000);

      if (signal_ != 0) break;

      if (strcmp(dirEntry -> d_name, ".") == 0 ||
              strcmp(dirEntry -> d_name, "..") == 0)
      {
        continue;
      }      

      n++;

      if (strlen(dirEntry -> d_name) == (MD5_LENGTH * 2 + 2) &&
              (strncmp(dirEntry -> d_name, "I-", 2) == 0 ||
                  strncmp(dirEntry -> d_name, "S-", 2) == 0 ||
                      strncmp(dirEntry -> d_name, "C-", 2) == 0))
      {
        file = new File();

        char *fileName = new char[fileSize];

        if (file == NULL || fileName == NULL)
        {
          #ifdef WARNING
          *logofs << "Keeper: WARNING! Can't add file '"
                  << dirEntry -> d_name << "' to repository.\n"
                  << logofs_flush;
          #endif

          delete [] fileName;

          delete file;

          continue;
        }

        strcpy(fileName, path);
        strcpy(fileName + baseSize, "/");
        strcpy(fileName + baseSize + 1, dirEntry -> d_name);

        file -> name_ = fileName;

        #ifdef DEBUG
        *logofs << "Keeper: Adding file '" << file -> name_
                << "'.\n" << logofs_flush;
        #endif

        if (stat(file -> name_, &fileStat) == -1)
        {
          #ifdef WARNING
          *logofs << "Keeper: WARNING! Can't stat NX file '"
                  << file -> name_ << ". Error is " << EGET()
                  << " '" << ESTR() << "'.\n"
                  << logofs_flush;
          #endif

          delete file;

          continue;
        }

        file -> size_ = fileStat.st_size;
        file -> time_ = fileStat.st_mtime;

        files_ -> insert(T_files::value_type(file));

        total_ += file -> size_;
      }
    }

    closedir(cacheDir);

    if (n == 0)
    {
      time_t now = time(NULL);

      if (now > 0 && stat(path, &fileStat) == 0)
      {
        #ifdef TEST
        *logofs << "Keeper: Empty NX subdirectory '" << path
                << "' unused since " << now - fileStat.st_mtime
                << " S.\n" << logofs_flush;
        #endif

        if (now - fileStat.st_mtime > EMPTY_DIR_TIME)
        {
          #ifdef TEST
          *logofs << "Keeper: Removing empty NX subdirectory '"
                  << path << "'.\n" << logofs_flush;
          #endif

          rmdir(path);
        }
      }
    }
  }
  else
  {
    #ifdef WARNING
    *logofs << "Keeper: WARNING! Can't open NX subdirectory '"
            << path << ". Error is " << EGET() << " '" << ESTR()
            << "'.\n" << logofs_flush;
     #endif

     cerr << "Warning" << ": Can't open NX subdirectory '"
          << path << ". Error is " << EGET() << " '" << ESTR()
          << "'.\n";
  }

  return 1;
}
Esempio n. 14
0
int Keeper::cleanupImages()
{
  #ifdef TEST
  *logofs << "Keeper: Looking for image directory in '"
          << root_ << "'.\n" << logofs_flush;
  #endif

  char *imagesPath = new char[strlen(root_) + strlen("/images") + 1];

  if (imagesPath == NULL)
  {
    return -1;
  }

  strcpy(imagesPath, root_);
  strcat(imagesPath, "/images");

  //
  // Check if the cache directory does exist.
  //

  struct stat dirStat;

  if (stat(imagesPath, &dirStat) == -1)
  {
    #ifdef WARNING
    *logofs << "Keeper: WARNING! Can't stat NX images cache directory '"
            << imagesPath << ". Error is " << EGET() << " '"
            << ESTR() << "'.\n" << logofs_flush;
    #endif

    cerr << "Warning" << ": Can't stat NX images cache directory '"
         << imagesPath << ". Error is " << EGET() << " '"
         << ESTR() << "'.\n";

    delete [] imagesPath;

    return -1;
  }

  //
  // Check any of the 16 directories in the
  // images root path.
  //

  char *digitPath = new char[strlen(imagesPath) + 5];

  strcpy(digitPath, imagesPath);

  for (char digit = 0; digit < 16; digit++)
  {
    //
    // Give up if we received a signal or
    // our parent is gone.
    //

    if (signal_ != 0)
    {
      #ifdef TEST
      *logofs << "Keeper: Signal detected. Aborting.\n"
              << logofs_flush;
      #endif

      goto KeeperCleanupImagesAbort;
    }
    else if (parent_ != getppid() || parent_ == 1)
    {
      #ifdef WARNING
      *logofs << "Keeper: WARNING! Parent process appears "
              << "to be dead. Returning.\n"
              << logofs_flush;
      #endif

      goto KeeperCleanupImagesAbort;

      return 0;
    }

    sprintf(digitPath + strlen(imagesPath), "/I-%01X", digit);

    //
    // Add to the repository all the files
    // in the given directory.
    //

    collect(digitPath);
  }

  delete [] imagesPath;
  delete [] digitPath;

  //
  // Remove the oldest files.
  //

  cleanup(images_);

  //
  // Empty the repository.
  //

  empty();

  return 1;

KeeperCleanupImagesAbort:

  delete [] imagesPath;
  delete [] digitPath;

  empty();

  return 0;
}
Esempio n. 15
0
int Keeper::cleanupCaches()
{
  #ifdef TEST
  *logofs << "Keeper: Looking for cache directories in '"
          << root_ << "'.\n" << logofs_flush;
  #endif

  DIR *rootDir = opendir(root_);

  if (rootDir != NULL)
  {
    dirent *dirEntry;

    struct stat fileStat;

    int baseSize = strlen(root_);

    int s = 0;

    while (((dirEntry = readdir(rootDir)) != NULL))
    {
      if (s++ % ONCE == 0) usleep(sleep_ * 1000);

      if (signal_ != 0) break;

      if (strcmp(dirEntry -> d_name, "cache") == 0 ||
              strncmp(dirEntry -> d_name, "cache-", 6) == 0)
      {
        char *dirName = new char[baseSize + strlen(dirEntry -> d_name) + 2];

        if (dirName == NULL)
        {
          #ifdef WARNING
          *logofs << "Keeper: WARNING! Can't check directory entry '"
                  << dirEntry -> d_name << "'.\n" << logofs_flush;
          #endif

          delete [] dirName;

          continue;
        }

        strcpy(dirName, root_);
        strcpy(dirName + baseSize, "/");
        strcpy(dirName + baseSize + 1, dirEntry -> d_name);

        #ifdef TEST
        *logofs << "Keeper: Checking directory '" << dirName
                << "'.\n" << logofs_flush;
        #endif

        if (stat(dirName, &fileStat) == 0 &&
                S_ISDIR(fileStat.st_mode) != 0)
        {
          //
          // Add to repository all the "C-" and
          // "S-" files in the given directory.
          //

          collect(dirName);
        }

        delete [] dirName;
      }
    }

    closedir(rootDir);
  }
  else
  {
    #ifdef WARNING
    *logofs << "Keeper: WARNING! Can't open NX root directory '"
            << root_ << "'. Error is " << EGET() << " '"
            << ESTR() << "'.\n" << logofs_flush;
     #endif

     cerr << "Warning" << ": Can't open NX root directory '"
          << root_ << "'. Error is " << EGET() << " '"
          << ESTR() << "'.\n";
  }

  //
  // Remove older files.
  //

  cleanup(caches_);

  //
  // Empty the repository.
  //

  empty();

  return 1;
}
Esempio n. 16
0
void Service::checkServiceStart(void)
{
  int status = 0;
  int wpid;
  int options = WNOHANG | WUNTRACED;

  static int timeout;

  //
  // The child is the service launched by nxservice.
  // Each second we check for the child exit status.
  // If the child doesn't return, we use its logs to
  // retrieve the status.
  //

  #ifdef DEBUG
  logUser("Service::checkServiceStart: going to check the '%s' service status", getType());
  #endif

  for (;;)
  {
    #ifdef TEST
    logUser("Service::checkServiceStart: waiting for child pid %d.", getPid());
    #endif

    wpid = waitpid(getPid(), &status, options);

    if (wpid == -1)
    {
      #ifdef WARNING
      logUser("WARNING! Waitpid returns error: %d.", EGET());
      #endif

      //
      // "The process specified does not exist or is not
      // a child of the calling process."
      // We don't know why this happened, but we can try
      // to return a successful state.
      //

      exit(0);
    }
    else if (wpid == 0)
    {
      //
      // The child's state is not changed. Let's check
      // if there is a reason to believe it is running.
      //

      if (checkStart())
      {
        #ifdef DEBUG
        logUser("Service::checkServiceStart: '%s' successfully starts after waiting "
                    "for %d seconds.", getType(), timeout / 1000);
        #endif

        exit(0);
      }
    }
    else
    {
      //
      // The child's state changes, let's figure out why.
      //

      if (WIFSTOPPED(status))
      {
        #ifdef DEBUG
        logUser("Service::checkServiceStart: '%s' service has been stopped with signal %d "
                    "after waiting for %d seconds.", getType(), WSTOPSIG(status),
                        timeout / 1000);
        #endif

        exit(0);
      }
      else if (WIFEXITED(status))
      {
        #ifdef DEBUG
        logUser("Service::checkServiceStart: '%s' service exits with status %d after "
                    "waiting for %d seconds.", getType(), WEXITSTATUS(status),
                        timeout / 1000);
        #endif

        exit(WEXITSTATUS(status));
      }
      else if (WIFSIGNALED(status))
      {
        #ifdef DEBUG
        logUser("Service::checkServiceStart: '%s' service terminates with signal %d after "
                    "waiting for %d seconds.", getType(), WTERMSIG(status),
                        timeout / 1000);
        #endif

        //
        // FIXME: Do we need to better classify the signals?
        //

        switch (WTERMSIG(status))
        {
          case SIGABRT:
          case SIGSEGV:
          case SIGKILL:
            exit(1);
          default:
            exit(0);
        }
      }
      else
      {
        #ifdef WARNING
        logUser("Service::checkServiceStart: WARNING! Waitpid returns an unknown status: "
                    "%d.", status);
        #endif
      }
    }

    usleep(SERVICE_START_INTERVAL * 1000);

    timeout += SERVICE_START_INTERVAL;

    if (timeout / 1000 >= getTimeout())
    {
      #ifdef WARNING
      logUser("Service::checkServiceStart: WARNING! Assuming the '%s' starts after "
                  "waiting for %d seconds.", getType(), timeout / 1000);
      #endif

      exit(0);
    }
  }
}
Esempio n. 17
0
int ServerProxy::handleNewXConnectionFromProxy(int channelId)
{
  //
  // Connect to the real X server.
  //

  int retryConnect = control -> OptionServerRetryConnect;

  int xServerFd;

  for (;;)
  {
    xServerFd = socket(xServerAddrFamily_, SOCK_STREAM, PF_UNSPEC);

    if (xServerFd < 0)
    {
      #ifdef PANIC
      *logofs << "ServerProxy: PANIC! Call to socket failed. "
              << "Error is " << EGET() << " '" << ESTR()
              << "'.\n" << logofs_flush;
      #endif

      cerr << "Error" << ": Call to socket failed. "
           << "Error is " << EGET() << " '" << ESTR()
           << "'.\n";

      return -1;
    }

    #ifdef TEST
    *logofs << "ServerProxy: Trying to connect to X server '"
            << xServerDisplay_ << "'.\n" << logofs_flush;
    #endif

    int result = connect(xServerFd, xServerAddr_, xServerAddrLength_);

    getNewTimestamp();

    if (result < 0)
    {
      #ifdef WARNING
      *logofs << "ServerProxy: WARNING! Connection to '"
              << xServerDisplay_ << "' failed with error '"
              << ESTR() << "'. Retrying.\n" << logofs_flush;
      #endif

      close(xServerFd);

      if (--retryConnect == 0)
      {
        #ifdef PANIC
        *logofs << "ServerProxy: PANIC! Connection to '"
                << xServerDisplay_ << "' for channel ID#"
                << channelId << " failed. Error is "
                << EGET() << " '" << ESTR() << "'.\n"
                << logofs_flush;
        #endif

        cerr << "Error" << ": Connection to '"
             << xServerDisplay_ << "' failed. Error is "
             << EGET() << " '" << ESTR() << "'.\n";

        close(xServerFd);

        return -1;
      }

      if (activeChannels_.getSize() == 0)
      {
        sleep(2);
      }
      else
      {
        sleep(1);
      }
    }
    else
    {
      break;
    }
  }

  assignChannelMap(channelId, xServerFd);

  #ifdef TEST
  *logofs << "ServerProxy: X server descriptor FD#" << xServerFd 
          << " mapped to channel ID#" << channelId << ".\n"
          << logofs_flush;
  #endif

  //
  // Turn queuing off for path proxy-to-X-server.
  //

  if (control -> OptionServerNoDelay == 1)
  {
    SetNoDelay(xServerFd, control -> OptionServerNoDelay);
  }

  //
  // If requested, set the size of the TCP send
  // and receive buffers.
  //

  if (control -> OptionServerSendBuffer != -1)
  {
    SetSendBuffer(xServerFd, control -> OptionServerSendBuffer);
  }

  if (control -> OptionServerReceiveBuffer != -1)
  {
    SetReceiveBuffer(xServerFd, control -> OptionServerReceiveBuffer);
  }

  if (allocateTransport(xServerFd, channelId) < 0)
  {
    return -1;
  }

  //
  // Starting from protocol level 3 client and server
  // caches are created in proxy and shared between all
  // channels. If remote proxy has older protocol level
  // pointers are NULL and channels must create their
  // own instances.
  //

  channels_[channelId] = new ServerChannel(transports_[channelId], compressor_);

  if (channels_[channelId] == NULL)
  {
    deallocateTransport(channelId);

    return -1;
  }

  increaseChannels(channelId);

  //
  // Propagate channel stores and caches to the new
  // channel.
  //

  channels_[channelId] -> setOpcodes(opcodeStore_);

  channels_[channelId] -> setStores(clientStore_, serverStore_);

  channels_[channelId] -> setCaches(clientCache_, serverCache_);

  int port = atoi(fontServerPort_);

  if (port > 0)
  {
    channels_[channelId] -> setPorts(port);
  }

  //
  // Let channel configure itself according
  // to control parameters.
  //

  channels_[channelId] -> handleConfiguration();

  //
  // Check if we have successfully loaded the
  // selected cache and, if not, remove it
  // from disk.
  //

  handleCheckLoad();

  return 1;
}
Esempio n. 18
0
int Process::start()
{
  logTrace("Process::start");

  int childIn[2]  = { -1, -1 };
  int childOut[2] = { -1, -1 };
  int childErr[2] = { -1, -1 };

  //
  // We either have 2 parameters and this process
  // will exec() a new command, or we have one or
  // none and this process will yield control to
  // a function.
  //

  if (function_ == NULL && (parameters_[0] == NULL ||
          parameters_[1] == NULL))
  {
    logTest("Process::start", "Can't start the process "
                "without a command or function");

    logError("Process::start", ESET(EPERM));

    return -1;
  }

  #ifdef TEST

  if (function_ == NULL)
  {
    logTest("Process::start", "Executing command '%s'",
                parameters_[0]);

    for (int i = 1; i < parametersLimit_ &&
             parameters_[i] != NULL; i++)
    {
      logTest("Process::start", "Parameter [%d] is '%s'",
                  i, parameters_[i]);
    }
  }
  else
  {
    logTest("Process::start", "Executing function at %p",
                function_);

    logTest("Process::start", "Passing data as %p",
                parameters_[0]);
  }

  for (int i = 0; i < environmentLimit_ &&
           environment_[i] != NULL; i++)
  {
    logTest("Process::start", "Environment [%d] is '%s'",
                i, environment_[i]);
  }

  #endif

  //
  // Create the pipes that will be used to replace
  // the standard descriptors.
  //

  if ((in_ == -1 && pipe(childIn) != 0) ||
          (out_ == -1 && pipe(childOut) != 0) ||
              (err_ == -1 && pipe(childErr) != 0))
  {
    logError("Process::start::pipe", EGET());

    return -1;
  }

  //
  // The fork() on Cygwin can show intermittent
  // failures. In this case we try again after
  // some time.
  //

  #ifdef __CYGWIN32__

  switch (pid_ = waitFork())

  #else

  switch (pid_ = fork())

  #endif

  {
    case -1:
    {
      //
      // An error was encountered.
      //

      logError("Process::start::fork", EGET());

      if (in_ == -1)
      {
        close(childIn[0]);
        close(childIn[1]);
      }

      if (out_ == -1)
      {
        close(childOut[0]);
        close(childOut[1]);
      }

      if (err_ == -1)
      {
        close(childErr[0]);
        close(childErr[1]);
      }

      return -1;
    }
    case 0:
    {
      //
      // We are the child process.
      //

      logTest("Process::start", "Child running with pid %d", getpid());

      //
      // Drop the privileges.
      //

      if (privileged_ != 1)
      {
        logTest("Process::start", "Child dropping the permissions");

        setgid(getgid());
        setuid(getuid());
      }

      //
      // Let the input descriptor inherited from the
      // parent replace the standard descriptors. The
      // descriptor can be either the one set by the
      // parent or our end of the pipe we created be-
      // fore forking.
      //
      // Handle the standard input.
      //

      if (in_ == -1)
      {
        logTest("Process::start", "Child replacing pipe "
                    "%d and %d for input", childIn[0], childIn[1]);

        if (childIn[0] != 0)
        {
          dup2(childIn[0], 0);

          close(childIn[0]);
        }

        close(childIn[1]);
      }
      else if (in_ != 0)
      {
        logTest("Process::start", "Child replacing input %d", in_);

        dup2(in_, 0);

        if (in_ != out_ && in_ != err_)
        {
          close(in_);
        }
      }
      else
      {
        logTest("Process::start", "Child inherited input");
      }

      in_ = 0;

      //
      // Handle the standard output.
      //

      if (out_ == -1)
      {
        logTest("Process::start", "Child replacing pipe "
                    "%d and %d for output", childOut[0], childOut[1]);

        if (childOut[1] != 1)
        {
          dup2(childOut[1], 1);

          close(childOut[1]);
        }

        close(childOut[0]);
      }
      else if (out_ != 1)
      {
        logTest("Process::start", "Child replacing output %d", out_);

        dup2(out_, 1);

        if (out_ != err_)
        {
          close(out_);
        }
      }
      else
      {
        logTest("Process::start", "Child inherited output");
      }

      out_ = 1;

      //
      // Handle the standard error.
      //

      if (err_ == -1)
      {
        logTest("Process::start", "Child replacing pipe "
                    "%d and %d for error", childErr[0], childErr[1]);

        if (childErr[1] != 2)
        {
          dup2(childErr[1], 2);

          close(childErr[1]);
        }

        close(childErr[0]);
      }
      else if (err_ != 2)
      {
        logTest("Process::start", "Child replacing error %d", err_);

        dup2(err_, 2);

        close(err_);
      }
      else
      {
        logTest("Process::start", "Child inherited error");
      }

      err_ = 2;

      //
      // Let the pid be our own pid.
      //

      pid_ = getpid();

      logTest("Process::start", "Child has descriptors "
                  "%d, %d, %d and pid %d", in_, out_, err_, pid_);

      //
      // Set the new environment for the process.
      //

      for (int i = 0; i < environmentLimit_ &&
               environment_[i] != NULL; i++)
      {
        putenv(environment_[i]);
      }

      //
      // Either execute the requested command or
      // yield control to the function.
      //

      if (parameters_[1] != NULL)
      {
        if (execvp(parameters_[0], parameters_ + 1) == -1)
        {
          logTest("Process::start", "Child failed to execute the command");

          logError("Process::start::execvp", EGET());
        }

        exitStatus(-1);
      }
      else
      {
        int result = function_((void *) parameters_[0]);

        exitStatus(result);
      }
    }
    default:
    {
      //
      // We are the parent process.
      //

      logTest("Process::start", "Parent started child with pid %d", pid_);

      if (in_ == -1)
      {
        close(childIn[0]);

        in_ = childIn[1];
      }

      if (out_ == -1)
      {
        close(childOut[1]);

        out_ = childOut[0];
      }

      if (err_ == -1)
      {
        close(childErr[1]);

        err_ = childErr[0];
      }

      logTest("Process::start", "Parent using descriptors %d, %d, %d",
                  in_, out_, err_);

      return 1;
    }
  }
}
Esempio n. 19
0
int StaticCompressor::compressBuffer(const unsigned char *plainBuffer,
                                         const unsigned int plainSize,
                                             unsigned char *&compressedBuffer,
                                                 unsigned int &compressedSize)
{
  #ifdef DEBUG
  *logofs << "StaticCompressor: Called for buffer at "
          << (void *) plainBuffer << ".\n"
          << logofs_flush;
  #endif

  compressedSize = plainSize;

  if (plainSize < (unsigned int) threshold_)
  {
    #ifdef TEST
    *logofs << "StaticCompressor: Leaving buffer unchanged. "
            << "Plain size is " << plainSize << " with threshold "
            << (unsigned int) threshold_ << ".\n" << logofs_flush;
    #endif

    return 0;
  }

  //
  // Determine the size of the temporary
  // buffer. 
  //

  unsigned int newSize = plainSize + (plainSize / 1000) + 12;

  //
  // Allocate a new buffer if it grows
  // beyond 64K.
  //

  if (buffer_ == NULL || (bufferSize_ > 65536 &&
          newSize < bufferSize_ / 2) || newSize > bufferSize_)
  {
    delete [] buffer_;

    buffer_ = new unsigned char[newSize];

    if (buffer_ == NULL)
    {
      #ifdef PANIC
      *logofs << "StaticCompressor: PANIC! Can't allocate compression "
              << "buffer of " << newSize << " bytes. Error is " << EGET()
              << " ' " << ESTR() << "'.\n" << logofs_flush;
      #endif

      cerr << "Warning" << ": Can't allocate compression buffer of "
           << newSize << " bytes. Error is " << EGET()
           << " '" << ESTR() << "'.\n";

      bufferSize_ = 0;

      return 0;
    }

    bufferSize_ = newSize;
  }

  unsigned int resultingSize = newSize; 

  int result = ZCompress(&compressionStream_, buffer_, &resultingSize,
                             plainBuffer, plainSize);

  if (result == Z_OK)
  {
    if (resultingSize > newSize)
    {
      #ifdef PANIC
      *logofs << "StaticCompressor: PANIC! Overflow in compression "
              << "buffer size. " << "Expected size was " << newSize
              << " while it is " << resultingSize << ".\n"
              << logofs_flush;
      #endif

      cerr << "Error" << ": Overflow in compress buffer size. "
           << "Expected size was " << newSize << " while it is "
           << resultingSize << ".\n";

      return -1;
    }
    else if (resultingSize >= plainSize)
    {
      #ifdef TEST
      *logofs << "StaticCompressor: Leaving buffer unchanged. "
              << "Plain size is " << plainSize << " compressed "
              << "size is " << resultingSize << ".\n"
              << logofs_flush;
      #endif

      return 0;
    }

    compressedBuffer = buffer_;
    compressedSize   = resultingSize;

    #ifdef TEST
    *logofs << "StaticCompressor: Compressed buffer from "
            << plainSize << " to " << resultingSize
            << " bytes.\n" << logofs_flush;
    #endif

    return 1;
  }

  #ifdef PANIC
  *logofs << "StaticCompressor: PANIC! Failed compression of buffer. "
          << "Error is '" << zError(result) << "'.\n"
          << logofs_flush;
  #endif

  cerr << "Error" << ": Failed compression of buffer. "
       << "Error is '" << zError(result) << "'.\n";

  return -1;
}
Esempio n. 20
0
FILE *Popen(char * const parameters[], const char *type)
{
  FILE *iop;

  struct pid *cur;
  int pdes[2], pid;

  if (parameters == NULL || type == NULL)
  {
    return NULL;
  }

  if ((*type != 'r' && *type != 'w') || type[1])
  {
    return NULL;
  }

  if ((cur = (struct pid *) malloc(sizeof(struct pid))) == NULL)
  {
    return NULL;
  }

  if (pipe(pdes) < 0)
  {
    free(cur);

    return NULL;
  }

  //
  // Block all signals until command is exited.
  // We need to gather information about the
  // child in Pclose().
  //

  DisableSignals();

  switch (pid = Fork())
  {
    case -1:
    {
      //
      // Error.
      //

      #ifdef PANIC
      *logofs << "Popen: PANIC! Function fork failed. "
              << "Error is " << EGET() << " '" << ESTR()
              << "'.\n" << logofs_flush;
      #endif

      cerr << "Error" << ": Function fork failed. "
           << "Error is " << EGET() << " '" << ESTR()
           << "'.\n";

      close(pdes[0]);
      close(pdes[1]);

      free(cur);

      return NULL;
    }
    case 0:
    {
      //
      // Child.
      //

      setgid(getgid());
      setuid(getuid());

      if (*type == 'r')
      {
        if (pdes[1] != 1)
        {
          //
          // Set up stdout.
          //

          dup2(pdes[1], 1);
          close(pdes[1]);
        }

        close(pdes[0]);
      }
      else
      {
        if (pdes[0] != 0)
        {
          //
          // Set up stdin.
          //

          dup2(pdes[0], 0);
          close(pdes[0]);
        }

        close(pdes[1]);
      }

      execvp(parameters[0], parameters + 1);

      exit(127);
    }
  }

  //
  // Parent. Save data about the child.
  //

  RegisterChild(pid);

  if (*type == 'r')
  {
    iop = fdopen(pdes[0], type);

    close(pdes[1]);
  }
  else
  {
    iop = fdopen(pdes[1], type);

    close(pdes[0]);
  }

  cur -> fp = iop;
  cur -> self = pid;
  cur -> next = pidlist;

  pidlist = cur;

  #ifdef TEST
  *logofs << "Popen: Executing ";

  for (int i = 0; i < 256 && parameters[i] != NULL; i++)
  {
    *logofs << "[" << parameters[i] << "]";
  }

  *logofs << " with descriptor " << fileno(iop)
          << ".\n" << logofs_flush;
  #endif

  return iop;
}