Please excuse my English, its not the best. Thank you.
I am suppose to write 2 simple programs, which are suppose to enable two communication between processes in/with named pipes(C++).
Each code search through the directory and (name of the directory is suppose to be inputed by a user) search for FIFO file type. After finding a file, first code opens to read, second code opens to write. If process can't find a file, then it will ask user to input a new path.
First code write the message in the terminal(stdin) and send it through the pipe to second process. Second process read the message from the pipe and shows it in terminal(stdout). Both processes are suppose to end after reading message from stdin and sending a statement 'END';
I am still learning and trying to find more about named pipes so for now I could only write some basics programs(just to read and write) but still I don't understand why both of them doesn't work.
Can You tell me what is wrong with my codes? Thank You.
here is my code for read
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
char sentence [256];
int fp, numr ,numop;
umask(0);
fp = mkfifo("myfifo", S_IFIFO|0666);
if(fp < 0)
{
printf("Cant make a file\n");
return 1;
}
numop = open("myfifo",O_RDONLY);
if(numop < 0)
{
printf("Cant open the file\n");
return 1;
}
numr = read(fp,&sentence,sizeof(sentence));
if( numr < 0)
{
printf("Cant read the message\n");
return 1;
}
fgets(sentence,256,stdin);
printf("Message: %s\n",sentence);
close(fp);
return 0;
}
here is for write
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int fd , numw;
char sentence [256];
fd = open("myfifo", O_WRONLY);
if(fd < 0)
{
printf("Can't open a file\n");
return 1;
}
printf ("Enter the message : ");
fgets(sentence,250,stdin);
numw = write(fd,sentence,strlen(sentence)+1);
if(numw < 0)
{
printf("Can write the message");
return 1;
}
close(fd);
return 0;
}
can you tell me what am I doing wrong?
Related
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
int main(){
int fd;
size_t size;
char name[]="aaa.fifо";
umask(0) ;
if (mknod(name, S_IFIFO | 0666, 0) < 0){
printf("Can\'t create FIFO\n");
_exit(-1);
}
if ((fd = open(name, O_WRONLY)) < 0){
printf("Can\'t open FIFO for writing\n");
_exit(-1);
}
char message[60];
while(true){
message[0] = 0;
std::cin.clear();
std::cin >> message;
if(!strcmp(message,"exit"))
{
printf("Exit to programm\n");
break;
}
size = write(fd, message, 60);
if (size < strlen(message)) {
printf("Can\'t write all string to FIFO\n");
_exit(-1);
}
}
close(fd);
return 0;
}
By typing, I realized that the problem arises when calling open ().
When I remove the loop the same trouble Even if cout at the beginning of main write nothing works, but when you remove the lines from open () everything works as it should
I realized that the problem arises when calling open ().
Some process must open the FIFO for reading, then your open() continues.
I want to edit the ns_last_pid file present in /proc/sys/kernel, but i'm getting the error of Read-only file system. How to resolve this?
This is what i've written to open the file.
int fd = open("/proc/sys/kernel/ns_last_pid", O_RDWR | O_CREAT, 0644);
if (fd < 0) {
cout<<strerror(errno)<<"\n";
return 1;
}
I've to write this file, change it's value. This file contains a single number represnting the last pid allocated to any process. I've to edit this so that i can get desired pid number for a process. like these guys are doing for their project CRIU(see first link).
Pid_restore(criu.org),
How to set process ID in Linux for a specific program(stackoverflow answer)
EDIT 1: Smallest reproducible example
#include <fstream>
#include <bits/stdc++.h>
#include <sys/types.h>
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/syscall.h>
using namespace std;
int main(){
printf("Opening ns_last_pid...\n");
int fd = open("/proc/sys/kernel/ns_last_pid", O_RDWR | O_CREAT, 0644);
if (fd < 0) {
cout<<strerror(errno)<<"\n";
return 1;
}
printf("Locking ns_last_pid...\n");
if (flock(fd, LOCK_EX)) {
close(fd);
printf("Can't lock ns_last_pid\n");
return 1;
}
printf("Done\n");
char buf[100];
int pid_max = 30000;
snprintf(buf, sizeof(buf), "%d", pid_max-1);
printf("Writing pid-1 to ns_last_pid...\n");
cout<<fd<<"\n";
if (write(fd, buf, strlen(buf)) != strlen(buf)) {
cout<<strerror(errno)<<"\n";
printf("Can't write to buf\n");
return 1;
}
printf("Done\n");
printf("Cleaning up...");
if (flock(fd, LOCK_UN)) {
printf("Can't unlock");
}
close(fd);
printf("Done\n");
return 0;
}
For a program to change kernel files, it should be owned by root
sudo chown root program // program is the executable(the binary)
set the setuid bit on the executable to execute a program with superuser access.
with this it will run as root even if we execute it as any user on our machine.
sudo chmod u+s program
Compile the source code and run the program with sudo to prevent other permission access errors.
Thanks to TedLyngmo for suggesting this solution.
I am trying to run a code in C++ that takes the reading from raspberry pi3 using DS18B20 . The code is compiled without errors but when i try to run it . It gives an error of segmentation fault .
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <wiringPi.h>
#include <iostream>
#define BUFSIZE 128
using namespace std;
int main(void)
{
float temp;
int i, j;
size_t ret;
FILE *fd;
char buf[BUFSIZE];
char tempBuf[5];
char *buffer;
buffer = (char*) malloc (sizeof(char)*BUFSIZE);
while(1){
fd = fopen("/sys/bus/w1/devices/28-0000085c3551/w1_slave", O_RDONLY);
if(fd != NULL){
perror("open device file error");
break;
}
while(1){
ret = fread(buffer, sizeof(char), BUFSIZE, fd);
if(0 == ret){
break;
}
if(-1 == ret){
if(errno == EINTR){
continue;
}
std::cout<<"Read Error";
fclose(fd);
break;
}
}
for(i=0;i<sizeof(buf);i++){
if(buf[i] == 't'){
for(j=0;j<sizeof(tempBuf);j++){
tempBuf[j] = buf[i+2+j];
}
}
}
temp = (float)atoi(tempBuf) / 1000;
std::cout<< "%.3f C\n" << temp;
fclose(fd);
//delay(500);
}
}
`
In compiling no errors occcurs .
it(stackoverflow site) kept on asking to to add more details i have no more details to add this is the only problem i am facing and the above code is compiling but not running .Hopefully some of you can help
The second argument to the fopen() call must be a string, in your case it should be "r" to open the file in read-only mode
fopen() returns NULL if the file couldn't be opened, and a non-NULL pointer otherwise; your code that checks if (fd != NULL) should check if (fd == NULL) instead
As pointed out in a comment to your question, the expression buf[i+2+j] could access a location outside the buf array
tempBuf isn't guaranteed to have a string terminator character in it, so when you call atoi(tempBuf) this function could access past the end of the tempBuf array
I have a very simple source reading file descriptor which hangs.
Could anyone notice the problem the code has?
The first one is the problematic source and the second one is the working source found on the web. Two sources are almost identical.
First source
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char ** argv) {
int n, in;
char buf[1024];
if ((in = open(argv[1], O_RDONLY)<0)) {
perror(argv[1]);
return -1;
}
while((n = read(in, buf, sizeof(buf))) > 0 ) { //HANGS at THIS LINE!!!!!!!!!!!
printf("TEST\n");
}
close(in);
return 0;
}
Second Working source got from online
/*
* ============================================================================
* Name : sp_linux_copy.c
* Author : Marko Martinović
* Description : Copy input file into output file
* ============================================================================
**/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#define BUF_SIZE 8192
int main(int argc, char* argv[]) {
int input_fd; /* Input and output file descriptors */
ssize_t ret_in; /* Number of bytes returned by read() and write() */
char buffer[BUF_SIZE]; /* Character buffer */
/* Create input file descriptor */
input_fd = open (argv [1], O_RDONLY);
if (input_fd == -1) {
perror ("open");
return 2;
}
/* Copy process */
while((ret_in = read (input_fd, &buffer, BUF_SIZE)) > 0){
printf("TEST\n");
}
/* Close file descriptors */
close (input_fd);
}
By a funny coincidence, you are reading from stdin. This is because in your if(in = ... you misplaced some brackets.
What is happening is that first open(argv[1], O_RDONLY)<0 gets evaluated, and the result gets put into in. Since the result of open() is not smaller than zero (on succesfull open), in becomes 0. And stdin is the name for the filedescriptor which is zero (on most systems). So it is a valid file descriptor, and read is very happy to read from it. It is just not getting any, until you type something in your console.
quick fix:
if ( (in = open(argv[1], O_RDONLY)) < 0) {
I am trying to write a program that has two separate process that talk via named pipes. The client which sends a message to a server, and the server which needs to broadcast that message to all clients attached to it. So far, I can get a connection between the two, but I cannot get more than one message to work no matter what I have tried. Below is the code I have written that will allow a connection and transmission of a single message.
server.cpp:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#define FIFO_FILE_1 "/tmp/client_to_server_fifo"
#define FIFO_FILE_2 "/tmp/server_to_client_fifo"
int main()
{
int client_to_server;
int server_to_client;
char buf[BUFSIZ];
/* create the FIFO (named pipe) */
mkfifo(FIFO_FILE_1, 0666);
mkfifo(FIFO_FILE_2, 0666);
printf("Server ON.\n");
while (1)
{
/* open, read, and display the message from the FIFO */
client_to_server = open(FIFO_FILE_1, O_RDONLY);
server_to_client = open(FIFO_FILE_2, O_WRONLY);
read(client_to_server, buf, BUFSIZ);
if (strcmp("exit",buf)==0)
{
printf("Server OFF.\n");
break;
}
else if (strcmp("",buf)!=0)
{
printf("Received: %s\n", buf);
printf("Sending back...\n");
write(server_to_client,buf,BUFSIZ);
}
/* clean buf from any data */
memset(buf, 0, sizeof(buf));
close(client_to_server);
close(server_to_client);
}
close(client_to_server);
close(server_to_client);
unlink(FIFO_FILE_1);
unlink(FIFO_FILE_2);
return 0;
}
client.cpp:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <string.h>
#define FIFO_FILE_1 "/tmp/client_to_server_fifo"
#define FIFO_FILE_2 "/tmp/server_to_client_fifo"
int main()
{
system("clear");
int client_to_server;
int server_to_client;
char str[140];
printf("Input message to server: ");
scanf("%139[^\r\n]", str);
/* write str to the FIFO */
client_to_server = open(FIFO_FILE_1, O_WRONLY);
server_to_client = open(FIFO_FILE_2, O_RDONLY);
if(write(client_to_server, str, sizeof(str)) < 0){
perror("Write:");//print error
exit(-1);
}
if(read(server_to_client,str,sizeof(str)) < 0){
perror("Read:"); //error check
exit(-1);
}
printf("\n...received from the server: %s\n\n\n",str);
close(client_to_server);
close(server_to_client);
/* remove the FIFO */
return 0;
}
close(client_to_server);
close(server_to_client);
Remove these lines from while loop because when server has done its work for the first time it will close the pipe and you cant be able to proceed further in pipes.