Reputation: 81
I hope that someone can help me. I am making a program that sends a long variable to from the client to the server and the last must respond with a string. I would like to point out i am using onc-rpc framework(sunRPC if i am not mistaking).
This is my current header => msg.x
//msg.x
program MESSAGEPROG
{
version MESSAGEVERS
{
string FIBCALC(long) = 1;
} = 1;
} = 0x20000001;
My server stub must implement this function. I will not put all the code because it's a homework assigment.
My server stub => server.c
#include <rpc/rpc.h>
#include <stdio.h>
#include <stdlb.h>
#include "msg.h"
char ** fibcalc_1_svc(whatToUse, dummy)
long *whatToUse;
struct svc_req *dummy;
{
char whatToSend;
whatToSend = (char **)malloc(sizeof(char*));
*whatToSend = (char *)malloc(sizeof(char) * STRING_SIZE);
//............
return whatToSend;
}
Needless to say the rest implementation works without the rpc. If i printf the string it works on a non rpc C file.
#include <rpc/rpc.h>
#include <stdio.h>
#include <stdlb.h>
#include "msg.h"
int main(int argc, char *argv[])
{
CLIENT *cl;
char **result;
long *whatToSend, *test;
FILE *fout, *fin;
whatToSend = (long *)malloc(sizeof(long));
result = (char **)malloc(sizeof(char*));
*result = (char *)malloc(sizeof(char) * STRING_SIZE);
if(argc != 3)
{
/* if arguments are not passed corectly
* we print the following message and close with exit error
*/
fprintf(stderr, "usage : ./%s [server ip] [fileIn]\n", argv[0]);
exit(1);
}
cl = clnt_create(argv[1],
MESSAGEPROG,
MESSAGEVERS,
"tcp");
if(cl == NULL)
{
/* if no connection to server
* we print the following message and close with exit error
*/
clnt_pcreateerror(argv[1]);
exit(1);
}
/* Sanity checks for file handle
*/
fin = fopen(argv[2],"r");
if (fin == NULL)
{
fprintf(stderr, "Input handle could not be opened!\n");
exit(1);
}
fout = fopen("out.txt", "w");
if (fout == NULL)
{
fprintf(stderr, "Output handle could not be opened!\n");
exit(1);
}
while(fscanf(fin, "%ld", whatToSend) != EOF)
{
memset(*result, 0, STRING_SIZE);
result = fibcalc_1(whatToSend, cl);
if(result == NULL)
{
/* Server did not respond
*/
clnt_pcreateerror("localhost");
exit(1);
}
printf("%s\n", *result);
}
/* Sanity checks for closing the handles
*/
if(fclose(fin))
{
fprintf(stderr, "Input handle could not be closed!!\n");
exit(1);
}
if(fclose(fout))
{
fprintf(stderr, "Output handle could not be closed!!\n");
exit(1);
}
/* Free allocated memory
*/
free(whatToSend);
free(*result);
free(result);
exit(0);
}
When i receive the server message i get seg fault. When i gdb, and step the client program at
result = fibcalc_1(whatToSend, cl);
i get that the result address is 0x00
When i change the result type to let's say an int or long or w/e the result comes out nicely and the program works.
I would also like to point out that result is type char** because string is of type char * in onc-rpc and i came to realize that whatever variable the server function must return is the address of the return value.
I hope i explained well enough my problem. My first thought was that in the server function the char whatToSend[20] should be of type char * that i should allocate, but then how do i deallocate it?
Thank you in advance.
Upvotes: 1
Views: 3647
Reputation: 81
My problem was that when i tried to send the result from the server stub function i did not realize that what i send must be saved on .data(static declaration) or heap(malloc). My resolve was to change in the server stub the following.
char ** fibcalc_1_svc(whatToUse, dummy)
long *whatToUse;
struct svc_req *dummy;
{
char whatToSend;
whatToSend = (char **)malloc(sizeof(char*));
*whatToSend = (char *)malloc(sizeof(char) * STRING_SIZE);
//............
return whatToSend;
}
In the client i tried to free the result after the function call. Although i have memory leaks it works now. Thank you @chux for your help
Upvotes: 1