[Info-vax] calloc fails with access violation
Jose Cuevas
jcuevas at mac.com
Mon Aug 24 16:03:05 EDT 2009
On Aug 24, 3:01 pm, JF Mezei <jfmezei.spam... at vaxination.ca> wrote:
> Jose Cuevas wrote:
> > In the above code I can printf the pointer sIn and do a strlen without
> > problems,
>
> strlen counts bytes until it encounters a null character. It may run
> fine but return some gigantic number.
>
> The COBOL strings passed do not contain a null to indicate end of
> string. you "strlen" would work only because somewhere in accessible
> memory of the process, the strlen would encounter a null character.
>
> The C program must either be told explicitely (hardcoded or though an
> argument) the size of a string, or you must pass the COBO strings BY
> DESCRIPTOR and have the C program expect a descriptor structure at which
> point it can examine the structure to find the length of the string
> (allocated length) and the address where it is located.
1. Im not a VMS expert but by my interpretation the SHOW PROC shows a
constant memory usage. Our sys admin thinks the same.
2. As far as the information I have found (not much) Cobol passes
strings "By Reference" by default. I wrote a few C functions to
inspect the parameters received by the C code. I found that the string
length matches the COBOL picture. The pointers received from COBOL are
NULL terminated strings. Only char/void pointers work as function
arguments in C.
3. I did fix the "strlen(sIn) + 1" in the snippet (thanks for pointing
this), yet same results.
4. Most of the time the code crashes here on the call to calloc:
....
printf("POST=%s\n", payload);
printf("Calling Calloc for %i\n",strlen(payload) + 255);
int sz;
sz = strlen(payload) + 255;
char *outData = calloc(sz, sizeof(char)); //Payload + 255 http
headers
printf("Finished with calloc\n");
....
(see function at end of email...)
5. I google around and I could not find any examples of a C function
receiving an argument as a DESCRIPTOR. I did not test the CALL BY
DESCRIPTOR to see if it makes a difference.
7. I did found that variables with sub-variables must be treated as
arrays after looking at a code at IBM site, but it means that the C
function needs to know the size of each sub-variable.
http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=/com.ibm.aix.cbl.doc/tpsubw20.htm
I was looking to pass "E0-NOMBRE-COMPLETO" to the C function.But
instead I get an array in the C side.
05 E0-NOMBRE-COMPLETO.
10 E0-PATERNO PICTURE X(15).
10 E0-MATERNO PICTURE X(15).
10 E0-NOMBRE PICTURE X(14).
10 E0-INICIAL PICTURE X(01).
6. Any help would be appreciated...
void ckSendData(char *inHost, char *inService, char *inPort){
int i = 0;
int sockfd; /* connection socket descriptor */
char buf[1025]; /* client data buffer */
char url[255];
char *theService;
char *theHost;
char *payload = calloc(1025, sizeof(char) ); //1MB payload limit
includes http headers
replyCount =-1;
if(payload == NULL){
printf("Unable to get memory for payload\n");
return;
}
//printf("Starting\n");
int thePort = atoi(inPort);
theService = ckGetCobolString(inService);
theHost = ckGetCobolString(inHost);
struct sockaddr_in serv_addr; /* server socket address
structure */
struct hostent *server;
if(fieldCount < 0){
free(theService);
free(theHost);
free(payload);
return;
}
/* Lets build the payload */
//printf("Building payload\n");
for(i=0; i<=fieldCount; i++){
if(i>0) payload = strcat(payload, "&");
payload = strcat(payload, fieldsN[i]);
payload = strcat(payload, "=");
payload = strcat(payload, fieldsV[i]);
}
printf("POST=%s\n", payload);
printf("Calling Calloc for %i\n",strlen(payload) + 255);
int sz;
sz = strlen(payload) + 255;
char *outData = calloc(sz, sizeof(char)); //Payload + 255 http
headers
printf("Finished with calloc\n");
memset( &serv_addr, 0, sizeof(serv_addr) );
serv_addr.sin_family = AF_INET;
/*default error is no error*/
strcpy(status,"000");
/*create connection socket */
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
free(theService);
free(theHost);
free(payload);
free(outData);
strcpy(status,"500");
return;
}
/*printf("host=[%s]\n", theHost);*/
/*inet_aton("136.145.30.61", &serv_addr.sin_addr);*/
server = gethostbyname(theHost);
if (server == NULL) {
free(theService);
free(theHost);
free(payload);
free(outData);
strcpy(status,"001");
return;
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)
&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(thePort);
/*printf("address=[%d]\n", serv_addr.sin_addr.s_addr);*/
/*connect to specified host and port number*/
if ( connect(sockfd,(struct sockaddr *) &serv_addr, sizeof
(serv_addr)) < 0 ) {
/*printf("unable to connect\n");*/
free(theService);
free(theHost);
free(payload);
free(outData);
strcpy(status,"501");
return;
}
/*=========================
* Writing our payload
*==========================*/
sprintf(outData,"POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d
\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n
%s",theService, theHost, strlen(payload), payload);
/*printf("Outdata:\n%s\n", outData);*/
if ( send(sockfd, outData, strlen(outData)+1, 0) < 0 ){
strcpy(status,"502");
free(theService);
free(theHost);
free(payload);
free(outData);
return;
}
/* printf("envie get [%s]\n",obuf); */
/* READ */
free(payload);
free(outData);
if ( recv(sockfd, buf, sizeof(buf), 0) < 0 ){ strcpy
(status,"503"); return; }
/*printf("tengo el output, status=%s\n", status);*/
/*shutdown connection socket (both directions)*/
if ( shutdown(sockfd, 2) < 0 ){
free(theService);
free(theHost);
strcpy(status,"504");
return;
}
/* close connection socket */
if ( close(sockfd) < 0 ){
free(theService);
free(theHost);
strcpy(status,"505");
return;
}
free(theService);
free(theHost);
/*=========================
* Parse output
*==========================*/
/*printf("Output:\n%s\n", buf);*/
int state = 0;
int li = -1;
int vi = -1;
/*printf("Data received: %s\n", buf );*/
for(i=0;i<=strlen(buf);i++){
/*printf("(%c), ",buf[i]);*/
switch(state){
case 0:
if(buf[i] == '<'){
replyCount++;
state=1;
li=0;
}
break;
case 1:
if(buf[i] == '>'){
state = 2;
vi=0;
replyN[replyCount][li] = '\0';
}else{
replyN[replyCount][li++] = buf[i];
}
break;
case 2:
if((buf[i] == '<') && (buf[i+1] == '/')){
state = 3;
replyV[replyCount][vi] = '\0';
i = i + strlen(replyN[replyCount]) + 2;
}else{
replyV[replyCount][vi++] = buf[i];
}
break;
case 3:
/*printf("reply%d[%s]=%s\n",replyCount, replyN[replyCount], replyV
[replyCount]); */
state = 0;
break;
}
if(replyCount == 24) break;
}
}
More information about the Info-vax
mailing list