void forceRemoveDir(string dir) { size_t len = dir.length(); if (dir[len-1] == '/') dir[len-1] = '\0'; EXIT_IF_ERROR(exec("rm","-rf",dir.c_str()) != 0); if (dir[len-1] == '\0') dir[len-1] = '/'; }
string get_symlink_target(const string & symlink) { const size_t buf_size = 4096; char buf[buf_size+1]; // TODO (toole1): hack-y value ssize_t len = readlink(symlink.c_str(), buf, buf_size); EXIT_IF_ERROR(len < 0 || static_cast<size_t>(len) == buf_size, "Error getting target of symlink " + symlink); buf[len] = '\0'; return string(buf); }
// Originally from Simon Biber // http://bytes.com/topic/c/answers/545614-list-files-current-directory vector<string> get_files_in_dir(const string & dir, bool concatdir /* = true */) { EXIT_IF_ERROR(dir == "" || dir[dir.length()-1] != '/', "Directory name must end in a '/'"); vector<string> files; DIR * dirp = opendir(dir.c_str()); if (dirp == NULL) return files; struct dirent * ent = readdir(dirp); while (ent != NULL) { string file = ent->d_name; if (file != "." && file != "..") files.push_back(concatdir ? dir + file : file); ent = readdir(dirp); } closedir(dirp); return files; }
string getcwdstr() { int len = 256; char * buffer = new char[len]; char * ret = getcwd(&buffer[0], len - 1); while (ret == NULL && errno == ERANGE) { len *= 2; delete buffer; buffer = new char[len]; ret = getcwd(&buffer[0], len - 1); } EXIT_IF_ERROR(ret == NULL); string cwdstr(buffer); delete buffer; return cwdstr; }
static int access_client_startDaemon(int cpu_id) { /* Check the function of the daemon here */ char* filepath; char *newargv[] = { NULL }; char *newenv[] = { NULL }; char *safeexeprog = TOSTRING(ACCESSDAEMON); char exeprog[1024]; struct sockaddr_un address; size_t address_length; int ret; pid_t pid; int timeout = 1000; int socket_fd = -1; if (config.daemonPath != NULL) { strcpy(exeprog, config.daemonPath); } else { strcpy(exeprog, safeexeprog); } if (access(exeprog, X_OK)) { ERROR_PRINT(Failed to find the daemon '%s'\n, exeprog); exit(EXIT_FAILURE); } pid = fork(); if (pid == 0) { if (cpu_id >= 0) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(cpu_id, &cpuset); sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); } ret = execve (exeprog, newargv, newenv); if (ret < 0) { //ERRNO_PRINT; ERROR_PRINT(Failed to execute the daemon '%s'\n, exeprog); exit(EXIT_FAILURE); } } else if (pid < 0) { ERROR_PLAIN_PRINT(Failed to fork); } EXIT_IF_ERROR(socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0), socket() failed); address.sun_family = AF_LOCAL; address_length = sizeof(address); snprintf(address.sun_path, sizeof(address.sun_path), "/tmp/likwid-%d", pid); filepath = strdup(address.sun_path); while (timeout > 0) { int res; usleep(1000); res = connect(socket_fd, (struct sockaddr *) &address, address_length); if (res == 0) { break; } timeout--; DEBUG_PRINT(DEBUGLEV_INFO, Still waiting for socket %s ..., filepath); } if (timeout <= 0) { ERRNO_PRINT; /* should hopefully still work, as we make no syscalls in between. */ fprintf(stderr, "Exiting due to timeout: The socket file at '%s' \ could not be opened within 10 seconds.\n", filepath); fprintf(stderr, "Consult the error message above this to find out why.\n"); fprintf(stderr, "If the error is 'no such file or directoy', \ it usually means that likwid-accessD just failed to start.\n"); exit(EXIT_FAILURE); }
// originally from stackoverflow.com user plinth // http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c // Modified by Jack Toole int8_t exec(int redirect_fd, const char * command, const char * arg1, const char * arg2, const char * arg3, const char * arg4, const char * arg5, const char * arg6) { int childExitStatus; pid_t pid; // For debugging: #if 0 cerr << "exec(" << command << ' ' << ((arg1!=NULL)?arg1:"-") << ' ' << ((arg2!=NULL)?arg2:"-") << ' ' << ((arg3!=NULL)?arg3:"-") << ' ' << ((arg4!=NULL)?arg4:"-") << ' ' << ((arg5!=NULL)?arg5:"-") << ' ' << ((arg6!=NULL)?arg6:"-") << ' ' << ')' << endl; #endif // avoid self destruction errors from closing then trying to duplicate output // you can't redirect to what's already there if (redirect_fd == STDOUT_FILENO || redirect_fd == STDERR_FILENO) redirect_fd = STDOUT_FILENO; // Save timer values :) // These are preserved across the parent, but not inherited by the child // let's change that struct itimerval remaining_real; struct itimerval remaining_virtual; struct itimerval remaining_prof; bool supports_virtual = true; bool supports_prof = true; EXIT_IF_ERROR(getitimer(ITIMER_REAL, &remaining_real)); if (getitimer(ITIMER_VIRTUAL, &remaining_virtual) != 0) { if (errno == EINVAL) { supports_virtual = false; errno = 0; } else internal::exit_if_error_output(__FILE__, __LINE__, "getitimer(ITIMER_VIRTUAL) failed"); } if (getitimer(ITIMER_PROF, &remaining_prof) != 0) { if (errno == EINVAL) { supports_prof = false; errno = 0; } else internal::exit_if_error_output(__FILE__, __LINE__, "getitimer(ITIMER_PROF) failed"); } pid = fork(); if (pid == 0) /* child */ { // Restore timers EXIT_IF_ERROR(setitimer(ITIMER_REAL, &remaining_real, NULL)); if (supports_virtual) EXIT_IF_ERROR(setitimer(ITIMER_VIRTUAL, &remaining_virtual, NULL)); if (supports_prof) EXIT_IF_ERROR(setitimer(ITIMER_PROF, &remaining_prof, NULL)); if (redirect_fd == -1) { int devnull_fd = open("/dev/null", O_WRONLY | O_NONBLOCK); close(STDOUT_FILENO); close(STDERR_FILENO); dup2(devnull_fd, STDOUT_FILENO); dup2(devnull_fd, STDERR_FILENO); close(devnull_fd); } else if (redirect_fd != STDOUT_FILENO) { close(STDOUT_FILENO); close(STDERR_FILENO); dup2(redirect_fd, STDOUT_FILENO); dup2(redirect_fd, STDERR_FILENO); } // Sanitize the environment #if 1 //!! hack! char path[] = "PATH=/bin/:/usr/bin:/usr/local/bin"; char redirect_glibc[] = "LIBC_FATAL_STDERR_=1"; char * newenv[] = { path, redirect_glibc, NULL }; //char * newenv[] = { path, NULL }; environ = newenv; #endif // Swap out child process image with the command, searching // in the specified path execlp(command, command, arg1, arg2, arg3, arg4, arg5, arg6, NULL); // An error occured cerr << "exec(" << '\"' << command << '\"'; if (arg1 != NULL) cerr << ", \"" << arg1 << "\""; if (arg2 != NULL) cerr << ", \"" << arg2 << "\""; if (arg3 != NULL) cerr << ", \"" << arg3 << "\""; if (arg4 != NULL) cerr << ", \"" << arg4 << "\""; if (arg5 != NULL) cerr << ", \"" << arg5 << "\""; if (arg6 != NULL) cerr << ", \"" << arg6 << "\""; cerr << ") failed: " << strerror(errno) << endl; exit(-1); } else if (pid < 0) { /* error - couldn't start process - you decide how to handle */ return -1; } else { /* parent - wait for child - this has all error handling, you * could just call wait() as long as you are only expecting to * have one child process at a time. */ pid_t ws = waitpid( pid, &childExitStatus, 0); if (ws == -1) { /* error - handle as you wish */ //cout << "exec error: " << __LINE__ << endl; return -1; } if (WIFEXITED(childExitStatus)) /* exit code in childExitStatus */ { int8_t status = WEXITSTATUS(childExitStatus); /* zero is normal exit */ /* handle non-zero as you wish */ return status; } else if (WIFSIGNALED(childExitStatus)) /* killed */ { kill(getpid(), WTERMSIG(childExitStatus)); return -1; } else if (WIFSTOPPED(childExitStatus)) /* stopped */ { //cout << "exec error: " << __LINE__ << endl; return -1; } else return -1; } }