1

when calling a ONC-RPC-function that returns a char array I get (apparently) uninitialized memory on the first call. Subsequent calls give me the correct result.

This example showcases the issue:

ftp.x:

const BLOCKSIZE = 1024;

struct block {
    char arr<BLOCKSIZE>;
};

program FILE_GET_BLOCK_PROG {
    version FILE_GET_BLOCK_VERS {
        block FILE_GET_BLOCK() = 1;
    } = 1;
} = 0x42424243;

ftp_client.c:

#include "ftp.h"

#include <errno.h>
#include <string.h>

size_t
file_get_block_prog_1(char *host, char *buf)
{
    CLIENT *clnt;
    block  *result_1;

#ifndef DEBUG
    clnt = clnt_create (host, FILE_GET_BLOCK_PROG, FILE_GET_BLOCK_VERS, "udp");
    if (clnt == NULL) {
        clnt_pcreateerror (host);
        exit (1);
    }
#endif  /* DEBUG */

    result_1 = file_get_block_1(NULL, clnt);
    if (result_1 == (block *) NULL) {
        clnt_perror (clnt, "call failed");
    }
#ifndef DEBUG
    clnt_destroy (clnt);
#endif   /* DEBUG */

    memcpy(buf, result_1->arr.arr_val, result_1->arr.arr_len);
    return result_1->arr.arr_len;
}

int
main (int argc, char *argv[])
{
    char *host, *source_filename;
    char buf[BLOCKSIZE+1];
    int block_count;
    size_t bytes_read;

    if (argc < 2) {
        printf ("usage: %s server_host\n", argv[0]);
        exit (1);
    }
    host = argv[1];

    bytes_read = file_get_block_prog_1 (host, buf);
    buf[bytes_read] = '\0';
    printf("%d bytes:\n%s\n", bytes_read, buf);
    exit (0);
}

ftp_server.c:

#include "ftp.h"

#include <errno.h>
#include <string.h>
#include <sys/stat.h>

block *
file_get_block_1_svc(void *argp, struct svc_req *rqstp)
{
    static block  result;
    static int request = 1;
    char buf[BLOCKSIZE+1];
    size_t bytes_read;

    strcpy(buf, "This is just a simple test block. There is nothing relevant in here.");

    result.arr.arr_len = strlen(buf);
    result.arr.arr_val = buf;
    printf("Request #%d:\n%s\n", request++, buf);

    return &result;
}

When running the server and calling the client twice, this is my output: client:

$ ./ftp_client localhost
68 bytes:

$ ./ftp_client localhost
68 bytes:
This is just a simple test bock. There is nothing relevant in here.

server:

Request #1:
This is just a simple test bock. There is nothing relevant in here.
Request #2:
This is just a simple test bock. There is nothing relevant in here.

Is there any initialization I missed that I need to do before the first request? What else would cause this behavior?

Horstinator
  • 548
  • 1
  • 5
  • 18
  • 1
    You are destroying client and then copying result to the buf. I am not sure whether that is causing this problem. You can try copying first and then destroying client. – MayurK Nov 27 '16 at 14:53
  • Thanks for your comment. I now copy the result to the buffer before destroying the client, however, this did not change the behavior I see. – Horstinator Nov 27 '16 at 16:15
  • 1
    Could you pass the Request number also in the response message? I just want to know whether client is missing the first request OR it is receiving the first response message in the second request. Also Run client multiple times and confirm if the issue is only in the first run. – MayurK Nov 27 '16 at 17:00
  • I included your suggestions and the results confirm that it is always the server's first request that does not work properly, all subsequent ones, also with multiple calls to the client program do work properly. – Horstinator Nov 28 '16 at 08:57
  • 1
    I can see one issue in your server code. "buf" is a local variable and you are passing address of it to other function using result. Make it global OR Allocate memory for it and try. – MayurK Nov 28 '16 at 11:03
  • Thanks, this fixed my problem! I could've seen this earlier, since the result-struct is also statically allocated. – Horstinator Nov 28 '16 at 11:08
  • Also do not pass address of static pointer for result. It is better to allocate memory. Read this: http://stackoverflow.com/questions/453696/is-returning-a-pointer-to-a-static-local-variable-safe – MayurK Nov 28 '16 at 11:38

0 Answers0