Usually when a program call a scanf it waits until something is available in stdin to read from it. I am currently making a fifo for input and another one for output that will be used by another process to write an read from a background proccess. But, the background process seem not to wait for any scanf in it, does anyone know why?
Here is the code:
Background:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
int main()
{
int out, in, err;
char *cFifo = "/tmp/out";
char *cInFifo = "/tmp/in";
mkfifo(cFifo, S_IRUSR|S_IWUSR);
mkfifo(cInFifo, S_IRUSR|S_IWUSR);
out = open(cFifo, O_RDWR|O_TRUNC|O_NONBLOCK);
in = open(cInFifo, O_RDWR|O_TRUNC|O_NONBLOCK);
dup2(out, STDOUT_FILENO);
dup2(out, STDERR_FILENO);
dup2(in, STDIN_FILENO);
scanf("%*c");
while(1)
{
scanf("%*c");
printf("Hello\n");
fflush(stdout);
}
return 0;
}
Foreground:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
int main()
{
int out, in;
size_t i = 0;
char bufOut[1024];
char *cFifo = "/tmp/out";
char *cFifoIn = "/tmp/in";
out = open(cFifo, O_RDONLY);
in = open(cFifoIn, O_WRONLY);
while(1)
{
i =0;
while(!i)
{
i = read(out, bufOut, 1024);
}
if(i)
write(STDOUT_FILENO, bufOut, i);
}
return 0;
}
I have already tried to force write on the new input fifo but the result is the same.
I already checked for errors, and everything return the expected values, no -1 or any other errors associated with each function
Related
I am trying to create client server communication through named pipe. From my client I want to send current time. I am trying to use time() function but the time won't appear on my server side terminal. I just see provided text. What am I doing wrong?
server
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main() {
char *pathname = "/tmp/myfifo";
int make_fifo = mkfifo(pathname, 0666);
char str[80];
for(;;){
int opn = open(pathname, O_RDONLY);
read(opn, str, sizeof(str));
close(opn);
}
return 0;
}
client
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
int main() {
char *pathname = "/tmp/myfifo";
time_t current_time = time(0);
char str[80];
int fd = open(pathname, O_WRONLY);
fgets(str, 80, stdin);
write(fd, str, sizeof(str));
write(fd, (void*) current_time, sizeof(current_time));
close(fd);
return 0;
}
What am I doing wrong?
client: Not passing the address of current_time.*1
// write(fd, (void*) current_time, sizeof(current_time));
write(fd, ¤t_time, sizeof(current_time)); // Add &
server: not reading the time.
Ignoring return values of read()/write().
*1 Avoid casting like (void*) current_time. Casting tends to hide errors.
I am trying to create a simple fifo client/server. Whenever I compile the program and try to type some data in client, in server I am getting weird outputs such as:
How can I fix this?
server:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd;
mkfifo("/tmp/my_fifo", 0666);
for(;;){
fd = open("/tmp/my_fifo", O_RDONLY);
int d;
char buf[64];
read(fd, buf, sizeof(buf));
sscanf(buf, "%d", &d);
close(fd);
}
return 0;
}
client:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(){
int fd;
fd = open("/tmp/my_fifo", O_WRONLY);
int d;
scanf("%d", &d);
char buf[32];
sprintf(buf, "%d", d);
write(fd, buf,strlen(buf));
close(fd);
return 0;
}
I am trying to use 'FIFOs' and 'popen()' function for communication between multiple processes. Also, the first process is multithreaded for reading and writing operations.
Following is the C code for the processes:
P1 process (Q1.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
void* reader()
{
char string[64];
int rfd = open("FIFO",O_RDONLY);
while(1)
{
read(rfd,string,sizeof(string));
sleep(10);
printf("%s\n",string);
}
}
void* writer()
{
char string[64];
FILE *wfd = popen("./Q1_1","w");
int fd = fileno(wfd);
while(1)
{
scanf("%s",string);
write(fd,string,sizeof(string));
}
pclose(wfd);
}
int main()
{
if(mkfifo("FIFO",0666)==-1)
{
if(errno!=EEXIST)
{
return 1;
}
}
pthread_t r_thread,s_thread;
pthread_create(&r_thread,NULL,reader,NULL);
pthread_create(&s_thread,NULL,writer,NULL);
pthread_join(r_thread,NULL);
pthread_join(s_thread,NULL);
return 0;
}
P2 Process (Q1_1.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
int main()
{
FILE *fd = popen("./Q1_2","w");
char string[64];
int ffd = fileno(fd);
printf("P2Check");
while(1)
{
scanf("%s",string);
write(ffd,string,sizeof(string));
}
return 0;
}
P3 Process (Q1_2.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
int main()
{
char string[64];
if(mkfifo("FIFO",0666)==-1)
{
if(errno!=EEXIST)
{
return 1;
}
}
int wfd = open("FIFO",O_WRONLY);
printf("P3Check");
while(1)
{
scanf("%s",string);
write(wfd,string,sizeof(string));
}
}
However, after executing process P1 and providing input, there is no output as if the process is stuck. I suspect there is some issue with the multithreading but not sure.
Can I use the kill() function to send a signal to another process? It should be possible, but kill() fails and I can't understand why.
I have two programs (process_1 and process_2). The first one should set a signal handler to increase a variable, than create a child that uses execve and loads process_2. The other program should send the signal using kill(). I used the shared memory to share process_1's pid through a struct (because I have other variables to share). The code of the first program is as follows:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define KEY_SM 1234
static int value_to_change=0;
typedef struct keys{
pid_t pid_process;
}keynote;
static void test_handler(int signo){
if(signo=SIGUSR1){
printf("received SIGUSR1\n");
value_to_change++;
}
}
int main(){
if((signal(SIGUSR1, test_handler))==SIG_ERR) perror("Errore allocazione SIGUSR1");
int flags = S_IRUSR|S_IWUSR|IPC_CREAT;
size_t shm_size = sizeof(keynote);
int shm_id = shmget(KEY_MC, shm_size, flags);
keynote *chv = shmat(shm_id, NULL, 0);
chv->pid_process=getpid();
printf("%d\n",chv->pid_process);
int process_2;
process_2=fork();
if(process_2==0){
char* argv[]={"process_1", "process_2", NULL};
if((execve("process_2", argv, NULL))<0) perror("execve error");
exit(0);
}else if(process_2<0)perror("fork error");
return 0;
}
The second program code is:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define KEY_SM 1234
typedef struct keys{
pid_t pid_process;
}keynote;
static void signal_to_send(pid_t process){
int ret=kill(process, SIGUSR1);
printf("%d", ret);
}
}
int main(int argc, char **argv){
int pid_of_process_1;
int flags = S_IRUSR|S_IWUSR|IPC_CREAT;
size_t shm_size = sizeof(keynote);
int shm_id = shmget(KEY_MC, shm_size, flags);
keynote *chv = shmat(shm_id, NULL, 0);
signal_to_send(chv->pid_process);
return 0;
}
process_1 does not wait for process_2. It just exits immediately. At which point process_2 may not even have started. So when process_2 sends the signal, process_1 is likely to not exist anymore.
– kaylum
I'm writing a program that should run indefinitely maintaining the value of a variable. Two other programs could change the value of the variable. I use named pipes to receive and send the variable value to external programs.
Here is my code for the manager of the variable.
manager.c:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
char a = 'a';
void *editTask(void *dummy)
{
int fd;
char* editor = "editor";
mkfifo(editor, 0666);
while(1)
{
fd = open(editor, O_RDONLY);
read(fd, &a, 1);
close(fd);
}
}
void *readTask(void *dummy)
{
int fd;
char* reader = "reader";
mkfifo(reader, 0666);
while(1)
{
fd = open(reader, O_WRONLY);
write(fd,&a,1);
close(fd);
}
}
int main()
{
pthread_t editor_thread, reader_thread;
pthread_create(&editor_thread, NULL, editTask, NULL);
pthread_create(&reader_thread, NULL, readTask, NULL);
pthread_join (editor_thread, NULL);
pthread_join (reader_thread, NULL);
return 0;
}
This program uses pthreads to separately get external values for the variable and to communicate the current value of the variable to external programs.
The program that is able to write values to the variable is:
writer.c:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char** argv)
{
if(argc != 2)
{
printf("Need an argument!\n");
return 0;
}
int fd;
char * myfifo = "editor";
fd = open(myfifo, O_WRONLY);
write(fd, argv[0], 1);
close(fd);
return 0;
}
The program that could read the current value is:
reader.c:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd;
char * myfifo = "reader";
fd = open(myfifo, O_RDONLY);
char value = 'z';
read(fd, &value, 1);
printf("The current value of the variable is:%c\n",value);
close(fd);
return 0;
}
I ran these programs in my Ubuntu system as follows:
$ ./manager &
[1] 5226
$ ./writer k
$ ./reader
bash: ./reader: Text file busy
Why doesn't my system allow me to run this program?
Thank you.
You are trying to call both the FIFO and the reader program "reader".
Also, you have no error checking. You have no idea whether those calls to mkfifo and open succeeded or not. Adding this is critical before you attempt to do any troubleshooting.