I'm learning C and currently i'm trying to make a shell. Anyway i made a test program to figure out how multiple pipes work. I changed the program to use a single pipe command and it prints the result fine. Then i changed it back to this code where that runs it for 2 pipes, but i always get output 0. I really have no clue why the output is 0. Can you help me?
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
int main(int argc, char * argv[])
{
int j;
pid_t pid;
int pfd[4];
char * ls[] = {"ls","-l",0};
char * sort[] = {"sort","-u",0};
char * wc[] = {"wc","-l",0};
int fd = open("outputfolder.txt", O_WRONLY | O_CREAT | O_APPEND);
for ( int i = 0; i < 4; i++ )
{
if ( pipe(pfd + i*2) < 0 )
{
perror("pipe\n");
exit(EXIT_FAILURE);
}
}
for ( int i = 0; i <= 2; i ++ )
{
if ( i == 2 )
{
pid = fork();
if ( pid == 0 )
{
if ( dup2(pfd[(i-1)*2],0) < 0 )
{
perror("dup2\n");
exit(EXIT_FAILURE);
}
if ( dup2(fd,1) < 0 )
{
perror("dup2\n");
exit(EXIT_FAILURE);
}
for (j = 0; j < 4; j++ )
{
close(pfd[j]);
}
if ( execvp(wc[0],wc) < 0 )
{
perror("execvpwc\n");
exit(EXIT_FAILURE);
}
}
else if ( pid == -1 )
{
perror("fork\n");
exit(EXIT_FAILURE);
}
}
else if ( i != 2 )
{
pid = fork();
if ( pid == 0 )
{
if ( i != 0 )
{
if ( dup2(pfd[(i-1)*2],0) < 0 )
{
perror("dup2\n");
exit(EXIT_FAILURE);
}
}
if ( dup2(pfd[i*2+1],1) < 0 )
{
perror("dup2\n");
exit(EXIT_FAILURE);
}
for ( j = 0; j < 4; j++ )
{
close(pfd[j]);
}
if (i == 0)
{
if ( execvp(ls[0],ls) < 0 )
{
perror("execvpls\n");
exit(EXIT_FAILURE);
}
}
else if ( i == 1 )
{
if ( execvp(sort[0],sort) < 0 )
{
perror("execvpsort\n");
exit(EXIT_FAILURE);
}
}
}
else if ( pid == -1 )
{
perror("fork\n");
exit(EXIT_FAILURE);
}
}
}
for ( j = 0; j < 4; j++ )
{
close(pfd[j]);
}
while(waitpid(0,0,0)>=0);
return 0;
}
EDIT: The number that it should print should be 19 for my directory
Related
I'm trying to write a function that copies all of the values in source1 which are also found in source2 into a destination and then returns the number of elements copied into the destination.
int common_elements(int length, int source1[length], int source2[length], int destination[length])
{
int counter = 0;
int i = 0;
while (i < length) {
int j = 0;
while (j < length) {
if ( source1[i] == source2[j]) {
destination[counter] = source1[i];
counter++;
}
j++;
}
i++;
}
return counter;
}
The problem is e.g. given (common_elements(5, {1,2,3,4,5}, {1,2,3,2,1}, [])), the correct input should be
1,2,3
return value: 3
However, the program is accounting for the duplicates and produces :
1,1,2,2,3
return value: 5
which is incorrect.
How can I remedy this?
In this while loop
int j = 0;
while (j < length) {
if ( source1[i] == source2[j]) {
destination[counter] = source1[i];
counter++;
}
j++;
}
you are counting all elements in the array source2 that are equal to the element source1[i].
I can suggest the following solution provided that the source arrays may not be changed within the function.
#include <stdio.h>
size_t common_elements( int destination[],
const int source1[],
const int source2[],
size_t n )
{
size_t counter = 0;
for ( size_t i = 0; i < n; i++ )
{
size_t number = 1;
for ( size_t j = 0; j < i; j++ )
{
if ( source1[i] == source1[j] ) ++number;
}
for ( size_t j = 0; number && j < n; j++ )
{
if ( source1[i] == source2[j] ) --number;
}
if ( number == 0 ) destination[counter++] = source1[i];
}
return counter;
}
int main(void)
{
enum { N = 5 };
int source1[N] = { 1, 2, 3, 4, 5 };
int source2[N] = { 1, 2, 3, 2, 1 };
int destination[N];
size_t n = common_elements( destination, source1, source2, N );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", destination[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <time.h>
#include <string.h>
#ifdef STRERROR
extern char *sys_errlist[];
extern int sys_nerr;
char *undef = "Undefined error";
char *strerror(error)
int error;
{
if (error > sys_nerr)
return undef;
return sys_errlist[error];
}
#endif
#define CIAO_PS "bfi_2"
main(argc, argv)
int argc;
char **argv;
{
int lsock, csock, osock;
FILE *cfile;
char buf[4096];
struct sockaddr_in laddr, caddr, oaddr;
int caddrlen = sizeof(caddr);
fd_set fdsr, fdse;
struct hostent *h;
struct servent *s;
int nbyt;
unsigned long a;
unsigned short oport;
int i, j, argvlen;
char *bfiargv[argc+1];
char *fintops = CIAO_PS ;
if( argc < 4 )
{
fprintf(stderr,"Usage: %s localport remoteport remotehost fakeps\n",argv[0]);
return 30;
}
for( i = 0; i < argc; i++ )
{
bfiargv[i] = malloc(strlen(argv[i]) + 1);
strncpy(bfiargv[i], argv[i], strlen(argv[i]) + 1);
}
bfiargv[argc] = NULL;
argvlen = strlen(argv[0]);
if( argvlen < strlen(CIAO_PS) )
{
printf("Se vuoi fregare davvero ps vedi di lanciarmi almeno come superFunkyDataPipe !\n") ;
abort();
}
if(bfiargv[4]) fintops=bfiargv[4] ;
strncpy(argv[0], fintops, strlen(fintops));
for( i = strlen(fintops); i < argvlen; i++ )
argv[0][i] = '\0';
for( i = 1; i < argc; i++ )
{
argvlen = strlen(argv[i]);
for(j=0; j <= argvlen; j++)
argv[i][j] = '\0';
}
a = inet_addr(argv[3]);
if( !(h = gethostbyname(bfiargv[3])) && !(h = gethostbyaddr(&a, 4, AF_INET)) )
{
perror(bfiargv[3]);
return 25;
}
oport = atol(bfiargv[2]);
laddr.sin_port = htons((unsigned short)(atol(bfiargv[1])));
if( (lsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 )
{
perror("socket");
return 20;
}
laddr.sin_family = htons(AF_INET);
// laddr.sin_addr.s_addr = htonl(0);
laddr.sin_addr.s_addr = inet_addr("128.199.167.13");
if( bind(lsock, &laddr, sizeof(laddr)) )
{
perror("bind");
return 20;
}
if( listen(lsock, 1) )
{
perror("listen");
return 20;
}
if( (nbyt = fork()) == -1 )
{
perror("fork");
return 20;
}
if (nbyt > 0)
return 0;
setsid();
while( (csock = accept(lsock, &caddr, &caddrlen)) != -1 )
{
cfile = fdopen(csock,"r+");
if( (nbyt = fork()) == -1 )
{
fprintf(cfile, "500 fork: %s\n", strerror(errno));
shutdown(csock,2);
fclose(cfile);
continue;
}
if (nbyt == 0)
goto gotsock;
fclose(cfile);
while (waitpid(-1, NULL, WNOHANG) > 0);
}
return 20;
gotsock:
if( (osock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 )
{
fprintf(cfile, "500 socket: %s\n", strerror(errno));
goto quit1;
}
oaddr.sin_family = h->h_addrtype;
oaddr.sin_port = htons(oport);
memcpy(&oaddr.sin_addr, h->h_addr, h->h_length);
if( connect(osock, &oaddr, sizeof(oaddr)) )
{
fprintf(cfile, "500 connect: %s\n", strerror(errno));
goto quit1;
}
while( 1 )
{
FD_ZERO(&fdsr);
FD_ZERO(&fdse);
FD_SET(csock,&fdsr);
FD_SET(csock,&fdse);
FD_SET(osock,&fdsr);
FD_SET(osock,&fdse);
if( select(20, &fdsr, NULL, &fdse, NULL) == -1 )
{
fprintf(cfile, "500 select: %s\n", strerror(errno));
goto quit2;
}
if( FD_ISSET(csock,&fdsr) || FD_ISSET(csock,&fdse) )
{
if ((nbyt = read(csock,buf,4096)) <= 0)
goto quit2;
if ((write(osock,buf,nbyt)) <= 0)
goto quit2;
}
else if( FD_ISSET(osock,&fdsr) || FD_ISSET(osock,&fdse) )
{
if ((nbyt = read(osock,buf,4096)) <= 0)
goto quit2;
if ((write(csock,buf,nbyt)) <= 0)
goto quit2;
}
}
quit2:
shutdown(osock,2);
close(osock);
quit1:
fflush(cfile);
shutdown(csock,2);
quit0:
fclose(cfile);
return 0;
}
I've compiled it on Debian 6 squeeze. It used to work. I've added all the iptables rules but it still does the error.
I've no idea how to fix it now.
To run it it should be:
./proxymr 6900 6900 server hostip PLoginMR
./proxymr 6121 6121 server hostip PCharMR
./proxymr 5121 5121 server hostip PMapMR
and I get:
bind: Cannot assign requested address
How can i check if i am using right the dynamic allocation in my C code.
It is an assignment for uni. When i put my code in the auto corrector system of my professor i get an error for dynamic allocation. My code :
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdarg.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
int main( )
{
for(;;)
{
char *cmd,*splitcmd;
//*pr0,*pr1,*pr2 ;
size_t bufsize = 1024;
char pr1[bufsize];
char pr2[bufsize];
char pr0[bufsize];
//char pr3[40];
int i,j,nargc=0,characters;
char **cmdArray;
//size_t bufsize = 1024;
// size_t bufsizecmd =1024;
pid_t pid,wpid;
int status = 0;
char pr='$';
char exit1[10]="exit";
char *path;
path = getenv("PATH");
putchar(pr);
cmd = malloc(bufsize * sizeof*cmd);
characters = getline(&cmd,&bufsize,stdin);
//printf("cmd===> %s characters===> %d \n",cmd,characters);
if(cmd[characters-1]=='\n' )
{
cmd[characters-1]='\0';
characters--;
}
//printf("cmd===> %s characters===> %d \n",cmd,characters);
cmdArray = malloc(bufsize*sizeof*cmdArray );
for ( i = 0; i < bufsize; i++ )
{
cmdArray[i]=malloc(bufsize*sizeof*cmdArray );
}
splitcmd=strtok(cmd," ");
// printf(" cmd==== %s\n",cmd);
while((splitcmd))
{
strcpy(cmdArray[nargc],splitcmd);
if(cmdArray[nargc][(strlen(cmdArray[nargc]))-1]==' ')
cmdArray[nargc][(strlen(cmdArray[nargc]))-1]='\0';
//printf(" nargc====%d cmdArray===[%s] \n",nargc,cmdArray[nargc]);
nargc++;
splitcmd = strtok(NULL," ");
}
//printf(" pr0 %s \n",pr0);
//printf(" pr1 %s \n",pr1);
//printf(" pr2 %s \n",pr2);
strcpy(pr0,cmdArray[0]);
if (strcmp( pr0, exit1) == 0 )
{
//printf("---------->Eksodos apo to programma<---------- \n");
free(cmd);
return (0);
exit(0);
//return (0);
}
else
{
if ((pid=fork()) == 0)
{
if(nargc ==1 )
{
strcpy(pr0,cmdArray[0]);
char *argv[] = {path,NULL};
execvp(pr0,argv);
for ( i = 0; i < bufsize; i++)
{
free(cmdArray[i]);
}
free(cmdArray);
free(cmd);
exit(0);
}
else if(nargc==2)
{
strcpy(pr0,cmdArray[0]);
strcpy(pr1,cmdArray[1]);
char *argv[] = {pr0,pr1,NULL};
execvp(pr0,argv);
exit(0);
for ( i = 0; i < bufsize; i++)
{
free(cmdArray[i]);
}
free(cmdArray);
free(cmd);
exit(0);
}
else
{
strcpy(pr0,cmdArray[0]);
strcpy(pr1,cmdArray[1]);
strcpy(pr2,cmdArray[2]);
//printf("cmdddddddd****====%s \n",*cmdArray);
char *argv[] = {pr0,pr1,pr2,NULL};
execvp(argv[0],argv);
for ( i = 0; i < bufsize; i++)
{
free(cmdArray[i]);
}
free(cmdArray);
free(cmd);
exit(0);
}
}
wait(&status);
}
}
}
There is no corresponding free() for cmd = (char *)malloc(bufsize * sizeof(char));.
Also, this code block:
strcpy(pr0,cmdArray[0]);
if (strcmp( pr0, exit1) == 0 )
{
//printf("---------->Eksodos apo to programma<---------- \n");
free(cmd);
return (0);
exit(0);
//return (0);
}
will need this
for ( i = 0; i < bufsize; i++)
{
free(cmdArray[i]);
}
free(cmdArray);
before the
free(cmd);
In this code block, there are two exit() calls:
else if(nargc==2)
{
strcpy(pr0,cmdArray[0]);
strcpy(pr1,cmdArray[1]);
char *argv[] = {pr0,pr1,NULL};
execvp(pr0,argv);
exit(0);
for ( i = 0; i < bufsize; i++)
{
free(cmdArray[i]);
}
free(cmdArray);
free(cmd);
exit(0);
}
The one immediately after the execvp(pr0,argv); prevents any of the free() calls from being executed. It needs to be removed.
I am trying to execute multiple commands in my customised shell using pipe. While the code doesn't show any error, the terminal just hangs there without any output. My code snippet is as follows :
void exe_pipe(char *pipe1[])
{
int pipe_end[2*l], n=0;
for( i = 0; i < l; i++ ) {
pipe ( pipe_end + i*2 );
}
for( m = 0; m < (l+1); m++ ) // l is no. of pipes
{
pid = fork();
if( pid == 0 )
{
if ( m > 0 )
dup2( pipe_end[ (n-1)*2] , 0 );
if ( m < (l+1) )
dup2( pipe_end[ (n*2)+1] , 1 );
execlp( pipe1[m], pipe1[m], (char*)NULL );
}
}
for( i = 0; i < 2 * l; i++ )
{
close( pipe_end[i] );
}
while(waitpid(-1, NULL, 0) != -1);
}
Ok I think I got it. My edits :
for( m = 0; m < l+1; m++ )
{
pid = fork();
if( pid == 0 )
{
if ( m > 0 )
{
dup2( pipe_end[ (m-1)*2 ] , 0 );
}
if ( m < (l+1) )
{
dup2( pipe_end[ (m*2)+1 ] , 1 );
}
for(i = 0; i < 2 * l; i++){
close(pipe_end[i]);}
execlp( pipe1[m], pipe1[m], (char*)NULL );
}
}
When trying to run my program on Linux I get a segmentation fault. I am a novice with C. In doing research, I figure the reason is probably a loop running beyond the last index in one of the arrays and accessing memory it shouldn't. Any hints?
Program overview: takes in a file in a certain format and determines from that file that best place to eat at based on the voter's three top favorites and least favorite.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int outputToFile (int winner, char **restaurantList, char **voterNameList, int numberOfVoters, int **voterFavorites) {
int index;
FILE *output;
output = fopen ("output_1", "w"); //write mode
fprintf(output, "%s\n", restaurantList[winner]); // write out the winning restuarant
fprintf(output, "Happy:\n");
for (index = 0; index < numberOfVoters ; index++) { // write out the happy persons
if (voterFavorites[index][1] == winner || voterFavorites[index][2] == winner || voterFavorites[index][3] == winner) {
fprintf(output, "%s\n", voterNameList[index]);
}
}
fprintf (output, "Sad:\n");
for (index = 0; index < numberOfVoters ; index++) { // write out the sad persons
if (voterFavorites[index][4] == winner) {
fprintf(output, "%s\n", voterNameList[index]);
}
}
fclose (output);
}
int countScore (int **voterFavorites, int tallyCard[], int numberOfVoters, int numberOfRestaurants) {
int index;
for (index = 0; index < numberOfRestaurants; index++ ) {
tallyCard[index] = 0;
}
for (index = 0; index < numberOfVoters; index++) {
if (voterFavorites[index][1] != -999) {
tallyCard[voterFavorites[index][1]] = tallyCard[voterFavorites[index][1]] + 1;
} else if (voterFavorites[index][2] != -999) {
tallyCard[voterFavorites[index][2]] = tallyCard[voterFavorites[index][2]] + 1;
} else if (voterFavorites[index][3] != -999) {
tallyCard[voterFavorites[index][3]] = tallyCard[voterFavorites[index][3]] + 1;
}
if (voterFavorites[index][4] != -999) {
tallyCard[voterFavorites[index][4]] = tallyCard[voterFavorites[index][4]] - 1;
}
}
}
int determineWinner( int tallyCard[], int maxVotes, int **voterFavorites) {
int x, y, max = 0, min = 999, maxIndex, percent;
for ( x = 0 ; x < 20 ; x++ ) {
if (tallyCard[x] > max) {
maxIndex = x;
max = tallyCard[x];
}
if (tallyCard[x] < min) {
if (tallyCard[x] != -999) {
min = tallyCard[x];
}
}
}
percent = max/maxVotes * 100;
if ( percent >= 50) {
return maxIndex;
} else {
for(x = 0; x < maxVotes ; x++) {
for (y = 0; y < 4; y++) {
if (voterFavorites[x][y] == min) {
voterFavorites[x][y] == -999;
}
}
}
return -444;
}
}
void inputFromFile (void) {
int index, numberOfRestaurants, numberOfVoters, winner;
char *nor, *nov, **restaurantList = malloc(20 * sizeof(char*));;
char **voterNameList = malloc(100 * sizeof(char*));
int **voterFavorites = (int**) calloc(100, sizeof(int*)), tallyCard[20];
int *fav1, *fav2, *fav3, *notFav;
FILE *input;
for ( index = 0; index < 100; index++ ) {
voterFavorites[index] = (int*) calloc(4, sizeof(int));
voterNameList[index] = malloc(26 * sizeof(char));
}
for ( index = 0 ; index < 20; index++ ) {
restaurantList[index] = malloc(51 * sizeof(char));
}
input = fopen ("input_1", "r"); // !!! need to check if this will give an error. Refer to slide set 2-48
if( input == NULL ) {
perror("Error while opening the file.\n");
exit(1);
}
//get names of restaurants
fgets(nor, 51, input);
numberOfRestaurants = atoi(nor); //resolve char * to int
for ( index = 0 ; index < numberOfRestaurants ; index++ ) {
fscanf(input, "%s", restaurantList[index]);
}
//get info lines and names of voters and initial values
fgets(nov, 101, input);
numberOfVoters = atoi(nov); //resolve char * to int
for ( index = 0 ; index < numberOfVoters ; index++ ) {
fscanf(input, "%s %i %i %i %i", voterNameList[index], fav1, fav2, fav3, notFav);
voterFavorites[index][1] = *fav1-1;
voterFavorites[index][2] = *fav2-1;
voterFavorites[index][3] = *fav3-1;
voterFavorites[index][4] = *notFav-1;
}
//count total score for resturants
countScore (voterFavorites, tallyCard, numberOfVoters, numberOfRestaurants);
winner = determineWinner(tallyCard, numberOfVoters, voterFavorites); // !!! probably need to look into these max votes
while (winner < 0) {
countScore(voterFavorites, tallyCard, numberOfVoters, numberOfRestaurants);
winner = determineWinner(tallyCard, numberOfVoters, voterFavorites);
}
outputToFile(winner, restaurantList, voterNameList, numberOfVoters, voterFavorites);
}
int main (void)
{
inputFromFile();
return 0;
}
I've been working on this for a while but I'm sure this could be cleaned up a bit. Sorry about that!
char *nor, *nov, **restaurantList = malloc(20 * sizeof(char*));;
/* ... */
fgets(nor, 51, input);
nor object is not initialized.