[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