/* 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); }
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); }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
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_; }
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; }
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; }
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; }
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); } } }
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; }
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; } } }
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; }
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; }