while is not recognized (system call-c) - loops

i have a little problem. i have this code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h> // serve per le FIFO
#include <fcntl.h> // serve per la open
#include <stdbool.h>
#define BUF_SIZE 100
int main (int argc,char *argv[]){
----definition of variables----
if (argc > 3) {
printf("Errore troppi argomenti da riga di start\n");
return -1;
}
if (argc < 2) {
printf("Errore pochi argomenti da riga di start\n");
return -1;
}
if(argc == 3){
pathServer=argv[1];
pathClient=argv[2];
printf("Ho stampato da riga di comando %d parametri.\n", argc);
}
if(argc == 2){
pathServer=argv[1];
printf("Ho stampato da riga di comando %d parametri.\n", argc);
}
if((mkfifo(pathClient, S_IWUSR | S_IRUSR)) < 0){
printf("Errore. FifoClient non creata.\n");
return -1;
}
fifoServer=open(pathServer, O_WRONLY);
write(fifoServer, pathClient, strlen(pathClient));
fifoClient=open(pathClient, O_RDONLY);
while(contr1) {
printf ("Inserisci comando da eseguire:\n");
(other code)
}
the program does not go into the first while.
it do all control before while and afther that the terminal doesnt show nothing
i dont know why, please help me

Please clarify your problem a bit before we can answer this.
Do you mean it not recognise the first if or the first while? If you meant the while, then please give some advice about the variable contr1 in its condition. Where it comes from? What modifies its value?

Related

How can I create an unknown number of child processes?

I need my code to be able to read n lines from stdin (each line will be a command from the Linux terminal), give it to a child process and execute it. Then when that child process ends, the program must read text again and execute another child process so that there are always n child processes running. I have tried in various ways but it always only reads one line even if I write several through stdin it executes only one child process and waits for more standard input. N must be between the values ​​1 and 8.
Standard input must be read in blocks of 16 bytes, and each command cannot be larger than 128 bytes.
This is the code I have:
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#define BUF_SIZE 16
struct ordenes{
int num;
char *args[60];
};
typedef struct ordenes * ordenes;
void error(char * argv, int num_exit){
fprintf(stderr,"Uso: %s [-p NUMPROC]\n",argv);
fprintf(stderr,"Lee de la entrada estándar una sencuencia de líneas conteniendo órdenes para ser ejecutadas y lanza cada una de dichas órdenes en un proceso diferente.\n");
fprintf(stderr,"-p NUMPROC Número de procesos en ejecución de forma simultánea (1 <= NUMPROC <= 8)\n");
exit(num_exit);
}
ordenes leer(){
char * buf;
if ((buf = (char *) malloc(BUF_SIZE * sizeof(char))) == NULL){
perror("malloc()");
exit(EXIT_FAILURE);
}
const char espacio[1] = " ";
const char salto_linea[2] = "\n";
char *token;
ordenes orden = malloc(sizeof(orden));
char *line = (char *) malloc(sizeof(char)*128);
while((read(STDIN_FILENO,buf,BUF_SIZE))>0){
strcpy(line,buf);
}
if(sizeof(line)>128){
fprintf(stderr,"Error: Tamaño de línea mayor que 128.");
exit(EXIT_FAILURE);
}
orden->num=0;
token = strtok(line, espacio);
orden->args[orden->num] = token;
while(token != NULL){
token = strtok(NULL, espacio);
if(token!=NULL) {
orden->num+=1;
orden->args[orden->num] = token;
}
}
orden->num+=1;
orden->args[orden->num] = NULL;
return orden;
}
int ejecutar_proceso(ordenes orden){
pid_t pid;
int status;
switch(pid = fork()){
case -1:
perror("fork()");
exit(EXIT_FAILURE);
break;
case 0:
execvp(orden->args[0],orden->args);
fprintf(stderr,"execvp() failed\n");
exit(EXIT_FAILURE);
break;
default:
if(waitpid(pid,&status,0) == -1){
perror("wait()");
free(orden);
exit(EXIT_FAILURE);
}
free(orden);
break;
}
return 1;
}
int main(int argc, char *argv[]){
char *arg1;
char *arg2;
int opt;
int num_procesos=1;
int num=num_procesos;
if(argc > 3){
error(argv[0],EXIT_FAILURE);
}
while((opt = getopt(argc,argv,"p")) != -1){
switch(opt){
case 'p':
if(argv[2]==NULL){
error(argv[0],EXIT_FAILURE);
}
num_procesos = atoi(argv[2]);
if(num_procesos < 1 || num_procesos > 8){
fprintf(stderr,"Error: el número de procesos en ejecución tiene que estar entre 1 y 8.");
error(argv[0],EXIT_FAILURE);
}
break;
default:
num_procesos = 1;
break;
}
}
int i=0;
while(i==0){
if(num_procesos>0){
ordenes orden = leer();
num_procesos-=1;
num_procesos += ejecutar_proceso(orden);
}
}
return EXIT_SUCCESS;
}
The Makefile that should be able to compile it is the following:
CFLAGS=-Wall -ggdb3 -Werror -Wno-unused -std=c11 CC=gcc TARGETS=$(patsubst %.c,%,$(wildcard *.c))
all: $(TARGETS)
clean:
-rm -rf $(TARGETS)
.PHONY: clean all
And for example it should be able to pass tests like: echo -e "ls -l\nls -l" | ./mycode -p 1
In ejecutar_proceso the parent always calls waitpid immediately after fork, so it will not proceed until the child it just created has terminated.
If you want to immediately go on and create more processes, then don't call waitpid yet. Create all n processes first. Then enter a loop where you call waitpid, and each time it returns, call fork() to create a new process to replace the one that just exited.

Program with named pipes sometimes working sometimes fails

Hello I am trying to do a program in c that uses named pipes to communicate with another program but if i run it more than once it fails most of the time with occasionally working perfectly, even though i don't change anything between tests.
Here is the code for arbitro.c the program that i execute first
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char *argv[])
{
int fd,id1,cont_pront=0,i=0;
char nomejog[40]="",instrucao[40]="";
// FIFO file path
char * myfifo = "myfifo";
// Creating the named file(FIFO)
mkfifo(myfifo, 0666);
do{
fd = open(myfifo,O_RDONLY);
if(fd == -1){
fprintf(stdout, "Erro a abrir.\n");
}
// First open in read only and read
for(int i=0;i<2;i++){
read(fd, nomejog, 40); //Recebe o nome do jogador
read(fd, &id1,sizeof(id1)); //Recebe o id do primeiro jogador
fprintf(stdout, "Nome: %s -» %d\n", nomejog,id1);
cont_pront++;
}
fprintf(stdout, "Nº: %d\n", cont_pront);
//Now open in write mode and write
fd = open(myfifo,O_WRONLY);
if(fd == -1){
fprintf(stdout, "Erro a abrir.\n");
}
if(cont_pront >= 2){
cont_pront = -1;
}
write(fd, &cont_pront, sizeof(int));
close(fd);
// optind is for the extra arguments
// which are not parsed
for(; optind < argc; optind++){
if(i == 0){
printf("Duração do campeonato: %s\n", argv[optind]);
}else{
if(i == 1){
printf("Tempo de espera: %s\n", argv[optind]);
}
}
i++;
}
}while(strcmp(instrucao,"exit") != 0);
return 0;
}
and here is the code for cliente.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char *argv[]){
int fd1,cont_pront=0;
char nomejog[40]="";
// FIFO file path
char * myfifo = "myfifo";
// Creating the named file(FIFO)
mkfifo(myfifo, 0666);
// Open FIFO for write only
fd1 = open(myfifo, O_WRONLY);
//Enviar o nome do jogador ao arbitro
for(int i=0;i<2;i++){
write(fd1, nomejog,strlen(nomejog)+1); //Envia o nome do jogador já pronto
write(fd1,&i, sizeof(int)); //Envia o id
strcpy(nomejog,"pedro");
}
close(fd1);
//Receber quantos jogadores estão prontos
fd1 = open(myfifo, O_RDONLY);
read(fd1, &cont_pront, sizeof(int)); //Recebe o nome do jogador
if(cont_pront == -1){
//Tem jogadores necessários para começar o jogo
fprintf(stdout,"Existem jogadores suficientes, o campeonato vai ser iniciado...\n");
execl("GAMEDIR/game01","GAMEDIR/game01", NULL);
}else{
//Ainda não tem jogadores suficientes para começar o jogo
fprintf(stdout,"Nao tem jogadores suficientes para comecar o campeonato.\n");
}
close(fd1);
return 0;
}
if everything goes well this is supposed to say that there are enough players and the executes the game, but for some reason sometimes it repeats everything sending more players in blank or the client stops midway execution or even doesn't send the correct players in the first place

creating unknown amount of process in child without pipe and semaphore

I am trying to make a modified shell.
I have tried several times, I searched a lot on the net, but I cannot fix my problem. first of all I do not want to run this code by pipe or semaphore.
I think with semaphore it would be even more difficult, because I do not now how many process should be there (maybe I am wrong, but it seems at least in this way).
In the first way, program makes the file correctly, but I cannot run a loop until the user enter "exit". I am trying with while(1) but it does not give me more than one file and the stdin is active only once.
in the second way, the user can use stdin until he inserts "exit", but again,
it does not give more than one file, moreover there is nothing inside.
I am trying to mix these two ways, I tried for more than one day, but I do not understand where is the problem. By the way, I think in the second way,
it should be the file descriptor.
also, please let me know that do I use the wait system call correctly or not?
Thank you in advance.
/first way/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
//void MYshell(char *comm);
int main(){
/*
char cmd[100];
printf("<exit> closes shell\n");
printf("MYshell:$ ");
fscanf(stdin,"%s",cmd);
do{
if(strcmp(cmd,"exit")==0){
printf("shell has been closed.\n");
break;
exit(EXIT_SUCCESS);
}
MYshell(cmd);
printf("MYshell:$ ");
fscanf(stdin,"%s",cmd);
}while(1);
*/
//void MYshell(char *comm){
pid_t fork_ret;
int fd,dup_ret;
char cmd[100];
char name[100];
printf(" <exit> closes shell\n");
printf("MYshell:$ ");
fscanf(stdin,"%s",cmd);
if(strcmp(cmd,"exit")==0){
printf("shell has been closed.\n");
//break;
exit(EXIT_SUCCESS);
}
fork_ret = fork();
if(fork_ret == -1)
exit(1);
if(fork_ret == 0){
sprintf(name,"%d.log",getpid());
fd = open(name,O_CREAT | O_WRONLY,S_IRWXU|S_IRWXG|S_IRWXO);
if(fd<0){
printf("Error in opening or creating %s.\n",name);
exit(1);
}
dup_ret = dup2(fd,1);
if(dup_ret<0){
printf("Error in duplicating stdout descriptor.\n");
exit(1);
}
system(cmd);
close(fd);
exit(0);
}
//close(fd);
//exit(EXIT_SUCCESS);
if(fork_ret>0){
int stat;
pid_t child = wait(&stat);
printf("child = %d\n",child);
if(WIFEXITED(stat))
printf("ok\n");
else
printf("error\n");
}
wait(NULL);
exit(EXIT_SUCCESS);
}
/* second way*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
int fd;
char cmd[100];
void MYshell(void);
int main(){
pid_t fork_ret;
//int fd,dup_ret;
printf(" <exit> closes shell\n");
while(1){
printf("MYshell:$ ");
fscanf(stdin,"%s",cmd);
//tmp = fgets(cmd,sizeof(cmd),stdin);
if(strcmp(cmd,"exit")==0){
printf("shell has been closed.\n");
break;
exit(EXIT_SUCCESS);
}
}
fork_ret = fork();
if(fork_ret == -1)
exit(1);
if(fork_ret == 0){
MYshell();
exit(0);
}
if(fork_ret>0){
wait(NULL);
exit(0);
}
wait(NULL);
exit(EXIT_SUCCESS);
}
void MYshell(void){
char name[BUFSIZ];
int fd,dup_ret;
sprintf(name,"%d.log",getpid());
fd = open(name, O_CREAT|O_RDWR , S_IRWXU|S_IRWXG|S_IRWXO);
if(fd<0){
printf("Error in opening or creating %s.\n",name);
exit(1);
}
dup_ret = dup2(fd,1);
if(dup_ret<0){
printf("Error in duplicating stdout descriptor.\n");
exit(1);
}
system(cmd);
close(fd);
exit(0);
}

fork is giving weird output when trying to add variable from child to father after killing child in c

I have this weird problem with a program on which I create 2 processes with a fork(); then i search an array for a specific value entered by the user. in a test version I search for the value 6 in this array.
int vet[max]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,0,6};
so the output is:
ci sono 2 di 6
ci sono 1 di 6
here is my output statement: printf("ci sono %i di %i\n",l+j,k); (l is the child variable, j is the father variable and k is the number to search)
but I close the child process with a wait(&status); and did the output afterwards. Is there a way to combine the two variables of the different processes and output them together.
here is the full code:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h> //Fork
#include <sys/wait.h> //wait
#include <sys/types.h> //getpid
#include <time.h>
#define max 20
int main(){
int i,k,l=0,j=0,pid;
int status;
int vet[max]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,0,6};
//srand(time(NULL));
//for(i=0;i<max;i++){
// vet[i]=rand()%100+1;
//}
printf("Inserire il valore da trovare: ");
scanf("%i",&k);
pid=fork();
if(pid<0){
printf("ERRORE\r\n");
return 0;
}
if(pid==0){
for(i=0;i<max/2;i++){
if(vet[i]==k){
l++;
}
}
//printf("trovati figlio %i\n",l);
wait(&status);
}else{
for(i=max/2;i<max;i++){
if(vet[i]==k){
j++;
}
}
}
printf("ci sono %i di %i\n",l+j,k);
return 0;
}
Not really orthodox but you could do this:
if(pid!=0){
for(i=0;i<max/2;i++){
if(vet[i]==k){
l++;
}
}
//printf("trovati figlio %i\n",l);
wait(&j);
j = WEXITSTATUS(j);
}else{
for(i=max/2;i<max;i++){
if(vet[i]==k){
j++;
}
}
return j;
}

Why is this named pipe not printing the sent line?

The following server creates a named pipe when it's run like this:
./serverprogram -p nameofthepipe -t 99
the optarg after t indicates a number of threads to be created (not done here).
Anyway, the pipe isn't working here:
/* Open the first named pipe for reading */
int rdfd = open(pipeName, O_RDONLY);
/* Read from the first pipe */
int numread = read(rdfd, command_and_pid, 280);
printf("what's being read is %s \n", command_and_pid); // not printing!!1!
Why?
Server program:
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
int main (int argc, char * argv[])
{
char pipeName[30];
int numThreads;
char command_and_pid[280];
int opcion;
if (argc < 2) {
printf ("ERROR: Missing arguments\n");//
exit(1);
}
opterr = 0;
while ((opcion = getopt (argc, argv, "p:t:w")) != -1)
{
switch (opcion) {
case 'p': // -p indica el nombre del pipe
printf("The name of the pipe is: %s\n",optarg);
strcpy(pipeName, optarg);
break;
case 't'://-t indica los hilos
printf("The number of threads is: %s\n",optarg);
numThreads= atoi(optarg);
break;
case '?':
fprintf(stderr,"no reconozco esa opcion\n");
break;
}
}
int ret_val = mkfifo(pipeName, 0666);
if ((ret_val == -1) && (errno != EEXIST)) {
perror("Error creating the named pipe");
exit (0);
}
/* Open the first named pipe for reading */
int rdfd = open(pipeName, O_RDONLY);
/* Read from the first pipe */
int numread = read(rdfd, command_and_pid, 280);
printf("what's being read is %s \n", command_and_pid); // not printing!!1!
close(rdfd);
return 0;
}
Client program:
#include <unistd.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
int main (int argc, char * argv[])
{
char pipeName[30];
printf("write the name of the pipe used to write to the server \n");
fgets(pipeName,30, stdin);
/* Open the first named pipe for writing */
int wrfd = open(pipeName, O_WRONLY);
printf("write the name of the command you want to execute \n");
char command_and_pid[280];
char command[250];
fgets(command,250, stdin);
puts(command); //quitar
strcpy(command_and_pid,command);
strcat(command_and_pid," ");
int pipeIntId;
char pidstring [30];
int pid= getpid();
sprintf(pidstring,"%d", pid);
strcat(command_and_pid,pidstring);
int written;
written=write(pipeIntId,command_and_pid,280);
//write to the pipe
// send the command and pid
close(pipeIntId); // close write pipe
return 0;
}
In the client, fgets keeps the newline at the end of the line, so you'll need to strip that before opening the file.
Also, in the code as given, you're opening wrfd but writing to pipeIntId, which is uninitialized (though perhaps you are extracting something from a function here).

Resources