0

I'm trying to add NULL to a string to make execvp work. Here is my code :

void execCmd(char *cmd[]){
    int count = 0;
    while(strcmp(cmd[count],NULL) != 0) count++;
    cmd[count] = NULL;
    execvp(cmd[0], cmd);
    perror("execvp");
}

here is my body code. It works with pipe. Tell me if you need my client code too (even if I'm pretty sure it won't be useful because it works)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#define TAILLE_CHAINE 15500
int isPalindrome(char *t);
void execCmd(char *cmd[]);
void RemoveSpaces(char* source);
char *replace(const char *s, char ch, const char *repl);
int main()
{
    char tube_serveur[TAILLE_CHAINE]="tube_serveur.fifo";
    int sortieTube; /* pointera sur la sortie du tube serveur */
    int entree_tube;/* pointera sur le tube client */
    char chaineALire[TAILLE_CHAINE];/*chaine à lire dans le tube serveur*/
    char chaineAEcrire[TAILLE_CHAINE]; /*chaine à écrire dans le tube du client*/
    char **chaineCmd = malloc(sizeof(char*) * (250));
    char *tube_client;/*un pointeur pour la fonction strtok (chaineALire, ";") qui permet de segmenter chaineALire */
    char *mot;/* mot que le client veut tester si c'est un palindrome ou non */
    int i =0;
    do
    {   /***************** création tube serveur **********************/
        if(mkfifo(tube_serveur, 0644) != 0)
        {   fprintf(stderr, "Impossible de créer le tube nommé.\n");
            exit(EXIT_FAILURE);
        }
        /**************** Attente d'un appel client ******************/
        if((sortieTube = open (tube_serveur, O_RDONLY)) == -1)
        {
            fprintf(stderr, "Impossible d'ouvrir la sortie du tube nommé.\n");
            exit(EXIT_FAILURE);
        }
        read(sortieTube, chaineALire, TAILLE_CHAINE);
        unlink(tube_serveur);
        printf("%s\n", chaineALire);
        tube_client = strtok (chaineALire, ";");/* segmente la chaine par le séparateur ; donc tube_client vaut le nom du tube du client (1ère partie de la chaine)*/
        mot = strtok (NULL, ";");
        if ((strcmp(mot,",") == 0) || (strcmp(mot, "stop") == 0))/*Si le mot vaut FIN on le serveur inutile d'utiliser la fonction de palindrome */
        {
            execCmd(chaineCmd);
            int k =0;
            chaineCmd = NULL;
            chaineCmd = malloc(sizeof(char*) * (250));

        }
        if (strcmp(mot,"stop") == 0)/*Si le mot vaut FIN on le serveur inutile d'utiliser la fonction de palindrome */
        {
            memset( chaineAEcrire, '\0', sizeof(chaineAEcrire) );
            sprintf(chaineAEcrire,"Fin du serveur");
            //break;
        }
        chaineCmd[i] = malloc((strlen(mot) + 1) * sizeof(char));
        strcat(chaineCmd[i], mot);
        printf ("client : %s\n", tube_client);
        printf ("message : %s\n", mot);
        /************* Ecriture dans le tube client ********/
        unlink(tube_client);/*on détruit le dernier tube client*/
        if(mkfifo(tube_client, 0644) != 0)
        {   fprintf(stderr, "Impossible de créer le tube nommé.\n");
            exit(EXIT_FAILURE);
        }
        if((entree_tube = open(tube_client, O_WRONLY)) == -1)
        {   fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
            exit(EXIT_FAILURE);
        }

        else
        {
            if(isPalindrome(mot))/* Le mot est-il un palindrome? */
            {   memset(chaineAEcrire, '\0', sizeof(chaineAEcrire) );/*remplace toutes les cases de la chaine par \0 : vide la chaine*/
                sprintf(chaineAEcrire,mot);/*on écrit le mot dans la chaine*/
                strcat(chaineAEcrire, " est un palaindrome."); /* on indique que c'est un palindrome */
            }
            else
            {   memset( chaineAEcrire, '\0', sizeof(chaineAEcrire) );
                sprintf(chaineAEcrire,mot);
                strcat(chaineAEcrire, " n'est pas un palaindrome.");
            }
        }
        write(entree_tube,chaineAEcrire, TAILLE_CHAINE);/* réponse au client */
        i++;
    }
    while((strcmp(mot,"stop") != 0) );
    /************** Programme terminé *****************************/
    unlink(tube_serveur);
    printf("fin du serveur");
    return EXIT_SUCCESS;
}
int isPalindrome(char *t)
{   int i;/*emplacement de la lettre en commencant par le début (ex : t[0] puis t[1]...*/
    int j;/*emplacement de la lettre en commencant par le début (ex : t[n] puis t[n-1]...*/
    int n=strlen(t); /* taille de la chaine  */
    for(i=0,j=n-1;i<j;i++,j--)
    {   if(tolower(t[i])!=tolower(t[j])) /*on met en minuscule car A!=a or Anna est un palindrome */
        {     return 0;/*ce n'est pas un palindrome*/
        }
    }
    return 1;
}
void execCmd(char *cmd[]){
    execvp(cmd[0], cmd);
    perror("execvp");
}
char *replace(const char *s, char ch, const char *repl) {
    int count = 0;
    const char *t;
    for(t=s; *t; t++)
        count += (*t == ch);

    size_t rlen = strlen(repl);
    char *res = malloc(strlen(s) + (rlen-1)*count + 1);
    char *ptr = res;
    for(t=s; *t; t++) {
        if(*t == ch) {
            memcpy(ptr, repl, rlen);
            ptr += rlen;
        } else {
            *ptr++ = *t;
        }
    }
    *ptr = 0;
    return res;
}

How can I do this?

Thanks for helping

9
  • strcmp compares two character arrays. NULL is not a valid character array. Besides, if it already ends in NULL that's the same as '\0'. Commented Nov 18, 2016 at 22:20
  • You don't need to use strcmp to test for null. Just test the pointer against NULL. Commented Nov 18, 2016 at 22:23
  • What makes you think you need to add NULL to a string? Commented Nov 18, 2016 at 22:25
  • 2
    OK, here comes the confusion between the null-terminator and the NULL pointer.. Commented Nov 18, 2016 at 22:27
  • 1
    Ok, I'll post it soon Commented Nov 18, 2016 at 22:29

1 Answer 1

1

execvp() expects the last element to be a NULL pointer, not a \0 char to signal the end.

You call it like this:

static int example(const char * binary, int num_argv, char * argv[])
{
    argv[num_argv - 1] = NULL; /* ensure argv is NULL terminated. */
    int r = execvp(binary, argv);
    if(r < 0) // execvp() failed
    {
        perror("failed to execvp()");
        /* 
         * terminate the current process regardless
         * otherwise you could end up with a process stuck in limbo
         * which is particularly troublesome if you rely on 
         * a simple fork() + some kind of wait() in a parent process
         * to cleanup child processes
         */
        exit(255);
    }
    return r;
}
Sign up to request clarification or add additional context in comments.

8 Comments

Ok, I'll update this. But how can I add NULL to my string?
You do not need to add it to the string.What is calling execCmd
so can I do this? void execCmd(char *cmd[]){ execvp(cmd[0], cmd); perror("execvp"); }
You just want cmd[count] = NULL;.
Exactly, to be able to run my execvp
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.