read file descriptor HANGS - c++

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) {

Related

read and write doesn't work in named pipes c++

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?

QSerialPort cannot open with error code 11

I'm trying to communicate with a device which provided a serial port. When I use the example C program provided by the device producer, it was successfully connected and I can send/receive data. But when I use my C++ program with QSerialPort, the open() method returned false and the error() returned 11 (An unidentified error occurred, as described by Qt documentation). Could anyone please help me?
OS: Cent OS 6.9
gcc/g++: 4.8
Qt: 5.6.0
An example of connecting with QSerialPort:
#include <qserialport.h>
#include <qstring.h>
int main(int argc, const char *argv[])
{
QString portName = "/dev/corser/x64ExpCL4x1_s0";
QSerialPort *pSerial = new QSerialPort();
pSerial->setPortName(portName);
pSerial->setBaudRate(QSerialPort::Baud9600);
pSerial->setParity(QSerialPort::NoParity);
pSerial->setDataBits(QSerialPort::Data8);
pSerial->setStopBits(QSerialPort::OneStop);
pSerial->setFlowControl(QSerialPort::NoFlowControl);
bool success = pSerial->open(QIODevice::ReadWrite);
if (!success) {
printf("Error: %d\n", pSerial->error());
} else {
printf("Success.\n");
pSerial->close();
}
delete pSerial;
return 0;
}
This program prints out Error: 11.
Here is a C program which is excerpted from the device's example program. This program just try to connect the serial port and then close the connection. While the original example program is complicated. It is actually kind of a "Terminal" program which sends user-input commands to the device and prints out the responses from the device.
#include <unistd.h>
#include <termios.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <ctype.h> /* Character types */
#define TRUE 1
#define FALSE 0
typedef struct
{
int open; // Flag for current open status of port
int update; // Flag indicating parameter changes
char *port; // Current port to be opened
int iod; // I/O index for open device port
struct termios stty; // Terminal port control structure
} SCOM_CTL;
struct termios ttctl = {0};
struct termios ttsav = {0};
struct termios coctl = {0};
struct termios cnctl = {0};
#define OPEN 1
#define CLOSE 2
#define UPDATE 3
#define NO_UPDATE 4
SCOM_CTL scom;
int main( int argc, char **argv )
{
scom.port = "/dev/corser/x64ExpCL4x1_s0";
scom_init();
scom_open_port();
if (scom.open == OPEN)
{
fputs("\rSuccess.\r\n", stdout);
scom_close_port(scom.iod);
}
else
{
fputs("\rError.\r\n", stdout);
}
}
// Initialize the console (stdin) for raw access.
int scom_init()
{
int i;
scom.open = CLOSE;
scom.update = NO_UPDATE;
scom.iod = -1;
tcgetattr(0, &coctl); // Save a copy to restore stdin.
tcgetattr(0, &cnctl);
cfmakeraw( &cnctl); // Set stdin to raw !
tcsetattr(0, 0, &cnctl);
}
int scom_open_port()
{
int i, iod;
if (scom.open == OPEN)
{
close(scom.iod);
scom.open = CLOSE;
}
if ( (iod = open( scom.port, (O_RDWR | O_NOCTTY))) == -1)
{
conres(); /* Reset the console. */
fputs("term : Open Failure on device\n", stdout);
return -1;
}
scom.iod = iod;
scom.open = OPEN;
scom.update = NO_UPDATE;
}
int scom_close_port()
{
scom.open = CLOSE;
close(scom.iod);
}
int conres()
{
return(tcsetattr(0, 0, &coctl));
}
This program prints out Success.

Unable to send data using pipe to second app which I launched via exec (C++)

I have to pass some data from one application to another. I am using pipe for the same. My first application first writes to pipe and then execs second application. But while reading from pipe, it returns nothing.
I am forking a child process, in which I am passing some data using fd[1]. And later I am calling another app using exec.
The code to read data using fd[0] is in the second app. But I am not getting anything.
appLaunch.cpp
int main()
{
/*
This application will send parameters to another application
*/
int fd[2];
pid_t childpid;
char string[] = "Hello, world!\n";
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1],string,(strlen(string)+1));
printf("Starting app...\n");
execlp("/home/varun/Documents/c programs/C-IPC/app","/home/varun/Documents/c programs/C-IPC/app",NULL);
exit(0);
}
else
{
}
return(0);
}
app.cpp
int main(int argc, char *argv[])
{
/*
This application will read parameters from
calling process from file descriptors
*/
int fd[2],nbytes;
pipe(fd);
close(fd[1]);
char readbuffer[80];
/* Read in a string from the pipe */
nbytes = read(fd[0],readbuffer, sizeof(readbuffer));
printf("\nReceived string: %s", readbuffer);
}
Well, I got the solution.
I had to open a read pipe in child process of (process that calls another app) appLaunch.cpp and write pipe in parent process of appLaunch.cpp. And read it via STDOUT in another application i.e. app.cpp.
Here is solution code:
app.cpp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
int main(int argc, char *argv[])
{
/*
This application will read parameters from
calling process from file descriptors
*/
int nbytes;
printf("\n %s",argv[0]);
char readbuffer[80];
/* Read in a string from the pipe */
nbytes = read(0,readbuffer, sizeof(readbuffer));
printf("\nReceived string: %s", readbuffer);
argv[1] = readbuffer;
}
appLaunch.cpp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
int main()
{
/*
This application will send parameters to another application
*/
// printf("App Launcher is now live!\n");
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[1]);
dup2(fd[0],STDIN_FILENO);
printf("Starting app...\n");
execlp("/home/varun/Documents/c programs/C-IPC/app","/home/varun/Documents/c programs/C-IPC/app",NULL);
exit(0);
}
else
{
close(fd[0]);
dup2(fd[1],STDOUT_FILENO);
write(fd[1],string,(strlen(string)+1));
}
return(0);
}

C++ KeyboardEmulator

I'm trying to code a KeyBoard Emulator for Linux, first I thought to use python to achieve it, but all the libraries were using X (and I don't want to use it). I decided to code in C++ to write in the keyboard buffer. After a few days of learning C++ and doing some research on Linux and how the input system works, I came up with this:
#include <stdio.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sstream>
#include <unistd.h>
#define EV_PRESSED 1
#define EV_RELEASED 0
int Emulate(char character)
{
printf("Starting the keyboard buffer writer\n");
int fd = 0;
char *device = "/dev/input/event1";
//write to buffer
if( (fd = open(device, O_RDWR)) > 0 )
{
struct input_event event;
printf("The keyboard code is: %d \n", KEY_A);
event.type = EV_KEY;
event.value = EV_PRESSED;
event.code = KEY_A;
write(fd, &event, sizeof(struct input_event));
event.value = EV_RELEASED;
event.code = KEY_A;
write(fd, &event, sizeof(struct input_event));
close(fd);
}
return 0;
}
int main(int argc, char *argv[]){
for(int i=0; i < sizeof(argv[1])/sizeof(int); i++){
Emulate(argv[1][i]);//for each car in the argv 1 call Emulate
}
}
As you can see I'm writing manually KEY_A to press the a key. And I was wondering if there is a function or a way to change a char to the keycodes definded in the file /usr/include/linux/input-event-codes.h.
Thank you for your help !

simple client/server program using named pipes in linux

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.