polslinux
polslinux

Reputation: 1779

C functions returning string?

This is my code:

  void get_pass(char *p);

int main(){

    char *host, *user, *pass;

    host = malloc(64); /* spazio per max 64 caratteri */
    if(!host) abort(); /* se malloc ritorna NULL allora termino l'esecuzione */
    host[63] = '\0';   /* evitare un tipo di buffer overflow impostando l'ultimo byte come NUL byte */

    user = malloc(64);
    if(!user) abort();
    user[63] = '\0';

    pass = malloc(64);
    if(!pass) abort();
    pass[63] = '\0';

    /* Immissione di hostname, username e password; controllo inoltre i 'return code' dei vari fscanf e, se non sono 0, esco */
    fprintf(stdout,"--> Inserisci <hostname>: ");
    if(fscanf(stdin, "%63s", host) == EOF){
        fprintf(stdout, "\nErrore, impossibile leggere i dati\n");
        exit(EXIT_FAILURE);
    }
    fprintf(stdout,"\n--> Inserisci <username>: ");
    if(fscanf(stdin, "%63s", user) == EOF){
        fprintf(stdout, "\nErrore, impossibile leggere i dati\n");
        exit(EXIT_FAILURE);
    };
    fprintf(stdout, "\n--> Inserisci <password>: ");
    get_pass(pass);

    /* Stampo a video le informazioni immesse */
    fprintf(stdout, "\n\nHost: %s\nUser: %s\nPass: %s\n\n", host,user,pass);

    /* Azzero il buffer della password e libero la memoria occupata */
    memset(pass,0,(strlen(pass)+1));
    free(host);
    free(user);
    free(pass);

    return EXIT_SUCCESS;
}

void get_pass(char *p){
    /* Grazie a termios.h posso disabilitare l'echoing del terminale (password nascosta) */
    struct termios term, term_orig;
    tcgetattr(STDIN_FILENO, &term);
        term_orig = term;
        term.c_lflag &= ~ECHO;
        tcsetattr(STDIN_FILENO, TCSANOW, &term);
        /* Leggo la password e controllo il 'return code' di fscanf */
        if(fscanf(stdin, "%63s", p) == EOF){
        fprintf(stdout, "\nErrore, impossibile leggere i dati\n");
        tcsetattr(STDIN_FILENO, TCSANOW, &term_orig);
        exit(EXIT_FAILURE);
    };
        /* Reimposto il terminale allo stato originale */
        tcsetattr(STDIN_FILENO, TCSANOW, &term_orig);
}

I would like to know if it is correct that the function get_pass haven't a return code?

In this function I read the password with fscanf and then I think that I have to return it to the main program...but:

  1. I don't know how (with return p; I got a warning)
  2. It works also without return p; so I think that it is all ok...but I'm not so sure...

I don't understand how return work with functions.

Upvotes: 1

Views: 802

Answers (4)

Chimera
Chimera

Reputation: 6018

If you want to be able to allow spaces in the password you could use something like the following. Turn off line buffering and handle the password one character at a time instead of using fscanf.

    #include <stdio.h>
    #include <errno.h>
    #include <termios.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>

    void get_pass(char *p);
    void flushStdin( void );

    int main(){
        // what you have now in your code.
    }



    void flushStdin( void )
    {
        int c;

        while ((c = getchar()) != '\n' && c != EOF);

        return;
    }


    void get_pass(char *p){

    int i = 0;
    int c;
    /* Grazie a termios.h posso disabilitare l'echoing del terminale (password nascosta) */
    struct termios term, term_orig;

    tcgetattr(STDIN_FILENO, &term);

    term_orig = term;
    term.c_lflag &= ~ECHO;
    term.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
    /* Leggo la password e controllo il 'return code' di fscanf */

    flushStdin();
    while( (( c = getchar() ) != '\n') && (i < 63) )
    {
        if( c != 127 )  // did user hit the backspace key?
        {
            p[i++] = (char)c;
        }
        else
        {
            // null last character in password and backup to one space in string
            // should make sure i doesn't go negative... oops.
            if( i > 0 )
            {
                p[--i] = 0x00;
            }
        }
    }

    tcsetattr(STDIN_FILENO, TCSANOW, &term_orig);

    return;
}

Upvotes: 1

SeattleOrBayArea
SeattleOrBayArea

Reputation: 3118

int main() 
{
   char * password = NULL;

   get_pass(&password); //that is how you want to pass pointer to pointer

}

void get_pass(char **password) 
{

//1. get password using scanf from stdin or whatever way you want. 
//2. assign it to *password 
//3. no need to return anything

}

Remember, you need to handle memory allocation for password string. Let's say you want to fix the password size to MAX_PASS_SIZE, then allocate that much memory either in main() or in get_pass so that you don't corrupt your stack memory. The above snippet I wrote just shows how to populate value into password, which probably is your main question, i.e. pass a pointer to pointer.

Upvotes: 2

Burton Samograd
Burton Samograd

Reputation: 3638

get_pass is defined to return void, which is nothing. In this case the return value is passed through the parameter p.

Upvotes: 1

MByD
MByD

Reputation: 137332

  1. A function with void return type should not return anything.
  2. You can use the return; statement to return from the function to the caller at any point.
  3. If no return; statement has been reached, and the function reaches its end, the control is returned to its caller.

Upvotes: 2

Related Questions