How to use the delay of the signal using sigwait() - c++

on assignment I need to write a program which opens a channel pipe and gives rise to two descendant process and then the parent fills the channel from the input file and then sends the signal SIGQUIT to the descendants, who can read character from channel and send each other signals after reading the next symbol of SIGUSR1 and SIGUSR2 to another descendant was able to start reading, but there was a problem: in a loop reading the parent is stupor, and if debajo the steps then everything is fine and it exits the loop, or if the clean lines of the exec, then exit from the loop occurs. I don't understand what the problem might be. In descendants, I use sigwait to wait. I will present the codes of the parent and descendants below. Please tell me what's wrong? The code of the parent:
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <signal.h>
#include <wait.h>
using namespace std;
int main() {
sigset_t new_mask;
sigemptyset(&new_mask);
sigaddset(&new_mask, SIGUSR1);
sigaddset(&new_mask, SIGUSR2);
sigaddset(&new_mask, SIGQUIT);
sigprocmask(SIG_SETMASK, &new_mask, NULL);
int fildes[2];
pipe(fildes);
pid_t pid1;
pid_t pid2;
pid1 = fork();
if (pid1 == 0) {
//execl("1","1", "output1.txt", &fildes[0], &fildes[1],NULL);
close(fildes[0]);
_exit(0);
}
else {
pid2 = fork();
if (pid2 == 0) {
execl("2","2", "output2.txt", &fildes[0], &fildes[1], NULL);
close(fildes[0]);
_exit(0);
}
else {
close(fildes[0]);
cout<<"Parent"<<endl;
ifstream file("input.txt");
if (file.is_open()) {
string str;
bool t = true;
t = (bool)getline(file, str);
while(t){
write(fildes[1], &str[0], strlen(str.c_str()));
cout<<"PARENT пишет:" << str << endl;
cout<< "sdsdsds";
t = (bool)getline(file, str);
}
cout << "aaaaaaaaaaaaaaaaaaaaaaaaa";
killpg(0, SIGQUIT);
file.close();
}
int st1, st2;
waitpid(pid1, &st1, 0);
waitpid(pid2, &st2, 0);
close(fildes[1]);
exit(EXIT_SUCCESS);
}
}
return 0;
}
First child's code:
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <signal.h>
#include <wait.h>
#include <cerrno>
using namespace std;
int main(int argc, char** argv) {
int fildes[2];
fildes[0]=*argv[2];
fildes[1]=*argv[3];
close(fildes[1]);
sigset_t mask_sig;
sigemptyset(&mask_sig);
sigaddset(&mask_sig, SIGUSR1);
sigaddset(&mask_sig, SIGQUIT);
ofstream file;
int last_sig;
char ch;
file.open(argv[1], ios::app);
//file << read(fildes[0], &ch, 1) << endl;
sigwait(&mask_sig, &last_sig);
while(read(fildes[0], &ch, 1) > 0){
//file << "a" << endl;
file << ch;
killpg(0, SIGUSR2);
sigwait(&mask_sig, &last_sig);
}
killpg(0, SIGUSR2);
file.close();
return 0;
}
Second child's code:
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <signal.h>
#include <wait.h>
using namespace std;
int main(int argc, char** argv) {
int fildes[2];
fildes[0]=*argv[2];
fildes[1]=*argv[3];
close(fildes[1]);
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGQUIT);
sigset_t mask_sig;
sigemptyset(&mask_sig);
sigaddset(&mask_sig, SIGUSR2);
ofstream file;
int last_sig;
char ch;
file.open(argv[1], ios::app);
//sigwait(&mask, &last_sig);
sigwait(&mask_sig, &last_sig);
while(read(fildes[0], &ch, 1) > 0){
file << ch;
killpg(0, SIGUSR1);
sigwait(&mask_sig, &last_sig);
}
killpg(0, SIGUSR1);
file.close();
return 0;
}

Related

Having issues with mmap from within a function

I'm trying to write a function that has mmap within it, however when I try to access the memory from main(), it gets a segfault. Does anyone have any idea why?
Please ignore the MPI headers - it's for the later part of the project. I have commented out the mprotect line to see that it is an mmap fault as opposed to the handler not necessarily working
net_map.cpp:
#include <iostream>
#include <signal.h>
#include <sys/mman.h>
#include <mpi.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "net_map.h"
using namespace std;
void handler(int sig, siginfo_t* info, void* other)
{
void* address = info->si_addr;
cout << "\nSegfault Detected! [Address: " << address << "]\n" << endl;
int unprotectresult = mprotect(address, SIZE, PROT_READ|PROT_WRITE|PROT_EXEC);
if (unprotectresult == 0)
{
cout << "\nSuccessful mprotect (memory unprotected)!\n" << endl;
}else
{
cout << "\nMprotect unsuccessful\n" << endl;
}
}
void netmap (char filename[], char* mapped)
{
int file;
file = open(filename, O_RDWR);
mapped = (char*) mmap(NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, file, 0);
if (mapped == MAP_FAILED)
{
cout << "\nMap Failed!" << endl;
}
cout << mapped << endl;
}
main.cpp
#include <iostream>
#include <signal.h>
#include <sys/mman.h>
#include <mpi.h>
#include <unistd.h>
#include <array>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <array>
#include "net_map.h"
using namespace std;
int main(int argc, char* argv[])
{
struct sigaction segaction;
memset(&segaction, 0, sizeof(segaction));
segaction.sa_flags = SA_SIGINFO;
sigemptyset(&segaction.sa_mask);
segaction.sa_sigaction = handler;
sigaction(SIGSEGV, &segaction, NULL);
int i;
char* mapped;
networkpage sheet;
char filename[] = "hello.txt";
netmap(filename, mapped);
sheet.address = (void*)mapped;
cout << "\nAddress: " << sheet.address << endl;
//mprotect(sheet.address, SIZE, PROT_NONE);
memcpy(sheet.address, "k", 1);
munmap(sheet.address, SIZE);
return 0;
}

IPC using unnamed Pipes

First off, Hello and thanks for your help!
I'm trying to get an understanding of IPC with unnamed pipes. Specifically, I'm going to be communicating with Maxima to expand an input that was grabbed from stdin and sent to the input Maxima and then that output is sent to stdout. So simply read input from stdin send it to the child and then write the output to stdout. Currently, I've gotten it to output:
Input ">(x+2)^2"
(%o2) x^2+4x+4
which is correct, but there is a newline between the input and output which shouldn't be there and the (%o2) comes from the Maxima formatted output, so that also should not be there.
I guess my question now comes to two things:
1) How do I fix my output so that it is formatted without the trailing newline and the output indicator?
2) What about the following code can I fix? What can I make better? and Why? (My code is not yet near completion because I have another segment I wish to write)
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <errno.h>
#include <iostream> // cin, cout
#include <signal.h>
using namespace std;
int main(int argc, char* argv[]){
pid_t pid;
int status;
int count;
int fpipe[2];
string start = "display2d:false$expand("; string end = ");"; string inp, sent;
string quit = "quit();";
string buffer;
if(pipe(fpipe)){cerr<<"Pipe Failure" << endl; exit(1);}
if((pid = fork()) < 0){ cerr<<"Fork Failure"<<endl; exit(2);}
if(pid == 0){ // child process
close(0); // close stdin
dup(fpipe[0]); // copy stdin
close(fpipe[1]);
execlp("maxima", "maxima", "-q", (char*)0);
read(fpipe[0], (void*)buffer.c_str(), buffer.length());
cout << buffer << " 1" << endl;
exit(EXIT_FAILURE);
}
else{
if(argc == 1){ // parent process
//close(fpipe[0]);
close(1); // close stdout
//dup(fpipe[1]); // redirect stdout
while(1){
cout << ">";
cin >> buffer;
if(buffer == "quit"){
break;
}
buffer = start+buffer+end+'\n';
int dp = write(fpipe[1], buffer.c_str(), buffer.length());
//cout << buffer << endl;
waitpid(getpid(), &status, 0);
}
}
else if(argc > 1){ // just do it for # of argc
}
}
return 0;}
Sample input and output
$./expand
> (x+2)^2
x^2+4*x+4
Current output
(%o#) x^2+4*x+4

How to redirect stderr to file without any buffer?

Does anybody know how to redirect stderr into a file without buffering in? if it is possible could you show me a simple code in c++ language for linux (Centos 6) operating system..?!
In C
#include <stdio.h>
int
main(int argc, char* argv[]) {
freopen("file.txt", "w", stderr);
fprintf(stderr, "output to file\n");
return 0;
}
In C++
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int
main(int argc, char* argv[]) {
ofstream ofs("file.txt");
streambuf* oldrdbuf = cerr.rdbuf(ofs.rdbuf());
cerr << "output to file" << endl;
cerr.rdbuf(oldrdbuf);
return 0;
}
Another way to do this is with the following dup2() call
#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <unistd.h>
using std::cerr;
using std::endl;
int main() {
auto file_ptr = fopen("out.txt", "w");
if (!file_ptr) {
throw std::runtime_error{"Unable to open file"};
}
dup2(fileno(file_ptr), fileno(stderr));
cerr << "Write to stderr" << endl;
fclose(file_ptr);
}

Program1 Accepts Input From User, Then Program2 Prints Out To Screen

I have a server and a client program. Server program prompts user to enter text, then sends user input to client. The client prints out user text to screen. So far server program prompts user to enter text and when I run client program it displays nothing. Any recommendations to make programs work. Below are both programs.
// server.cpp
// g++ -o server server.cpp -lpthread -lrt
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string>
#include <ctype.h>
#include <iostream>
using namespace std;
string UserInput(string);
#define SHMSZ 27
char SEM_NAME[]= "vik";
int main(void)
{
char ch;
int shmid;
key_t key;
char *shm,*s;
sem_t *mutex;
string input;
//name the shared memory segment
key = 1000;
//create & initialize semaphore
mutex = sem_open(SEM_NAME,O_CREAT,0644,1);
if(mutex == SEM_FAILED)
{
perror("unable to create semaphore");
sem_unlink(SEM_NAME);
exit(-1);
}
//create the shared memory segment with this key
shmid = shmget(key,SHMSZ,IPC_CREAT|0666);
if(shmid<0)
{
perror("failure in shmget");
exit(-1);
}
//attach this segment to virtual memory
shm = (char*) shmat(shmid,NULL,0);
//start writing into memory
s = shm;
// Enter user input
//cout << "Enter your input: ";
//cin >> input;
// Display user input
//cout << "You entered: "<< input << endl;
//return 0;
while(1)
{
cout << "Enter your input: ";
cin >> input;
sem_wait(mutex);
//*s++ = count;
sem_post(mutex);
//return 0;
}
//the below loop could be replaced by binary semaphore
while(*shm != '*')
{
sleep(1);
}
sem_close(mutex);
sem_unlink(SEM_NAME);
shmctl(shmid, IPC_RMID, 0);
_exit(0);
}
-
// client.cpp
// g++ -o client client.cpp -lpthread -lrt
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
string UserInput(string);
#define SHMSZ 27
char SEM_NAME[]= "vik";
int main(void)
{
char ch;
int shmid;
key_t key;
char *shm,*s;
sem_t *mutex;
string input;
//name the shared memory segment
key = 1000;
//create & initialize existing semaphore
mutex = sem_open(SEM_NAME,0,0644,0);
if(mutex == SEM_FAILED)
{
perror("reader:unable to execute semaphore");
sem_close(mutex);
exit(-1);
}
//create the shared memory segment with this key
shmid = shmget(key,SHMSZ,0666);
if(shmid<0)
{
perror("reader:failure in shmget");
exit(-1);
}
//attach this segment to virtual memory
shm = (char*) shmat(shmid,NULL,0);
//start reading
s = shm;
while(1)
{
cout << "You entered: " << input << endl;
//cin >> input;
sem_wait(mutex);
putchar(*s);
sem_post(mutex);
return 0;
}
//once done signal exiting of reader:This can be replaced by another semaphore
*shm = '*';
sem_close(mutex);
shmctl(shmid, IPC_RMID, 0);
exit(0);
}

String Validation in a Certain Format

I'm creating a simple chess game which uses shared memory. There are two players (Black,White) in the game and they are working in Strict Alternation principle. I get input from every player in turn-based sense and use them. My question is: I want the user to give the input like mov(a1,b2). After getting the input First: I want to validate if it is in the correct format and then I want to use the a1,b2 values in a function. Here is the part of my code:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define SHMSZ 27
int main() {
int shmid;
key_t key;
char *shm;
string cmd;
int check =1;
key = 111;
/*
* Locate the segment.
*/
if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
perror("shmget");
return 0;
}
/*
* Now we attach the segment to our data space.
*/
if ((shm = (char*) shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
return 0;
}
cout << *shm << endl;
while(check)
{
if(*shm == '*') //checks if other player finished the game
{
cout<<"End of the game. Thank you for playing." <<endl;
*shm ='*';
exit(1);
}
while(*shm == 'B')
{
cout << "Enter a move" << endl;
cin >> cmd;
if(cmd=="eog") // Finish the game
{
cout<<"End of the game. Thank you for playing." <<endl;
*shm ='*';
exit(1);
}
*shm = 'W';
}
}
return 0;
}