Page 1 of 1

Using socket APIs in C program

PostPosted: Tue May 15, 2018 8:53 pm
by chong_zhou
Hi guys,

I'm kind of new to zOS and I am developing a small TCP/IP client program in C.

I wrote a prototype program in Linux (Ubuntu) and quickly got it compiled and executed. The result was as expected.

However, when I ported it to USS, It did not even compile. I searched and read a couple of unhelpful articles on IBM's knowledge centre, and finally got totally lost.

Here is a simplified version of the program: (the concrete questions are in the comment of the code)


#pragma langlvl(stdc99)
#define _XOPEN_SOURCE_EXTENDED 1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

int main(int argc, char const *argv[])
{
    /* ... ... ... */

    struct addrinfo hint = {0};
    hint.ai_flags = AI_CANONNAME;
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_protocol = 0;

    /* HERE COMES THE 1ST PROBLEM: no matter what I did, the compiler just couldn't find anything from netdb.h. AI_CANONNAME not found, getaddrinfo not found either */
    int rc = getaddrinfo(hostname, "", &hint, &result);

    /* ... ... ... */

    /* HERE COMES THE 2ND PROBLEM: 'socket' was found after I added the #pragma and the #define, BUT the linker couldn't find the module for the symbol 'socket' so I couldn't produce the executable file. I simply used the following command to build it:
        c99 -o test test.c
*/
    sock = socket(AF_INET, SOCK_STREAM, 0);

    /* ... ... ... */
    return 0;
}
 


IBM really has very limited articles that about these, so I really need help with it.

1. Why c89 compiler (and xlc did the same) failed to find getaddrinfo() ?
2. What linker options I need to use ?

Thank you very very much !!

Re: Using socket APIs in C program

PostPosted: Tue May 15, 2018 9:01 pm
by Robert Sample
As you have discovered, the z/OS system is unlike other systems -- even for Unix (for example, getaddrinfo on z/OS has 10 parameter values). There is a manual at https://www.ibm.com/support/knowledgece ... 01/soc.htm which talks about the API and the C Socket API in particular. You'll need to read in this manual to understand the differences and adapt your code to z/OS.

Re: Using socket APIs in C program

PostPosted: Tue May 15, 2018 9:47 pm
by chong_zhou
To @Robert Sample,

Thank you so....o much! I'll read the manual right away.

...and yes, you are right. The USS is just pretending to be Unix amd it should've tried harder to pretend.

Re: Using socket APIs in C program

PostPosted: Thu May 17, 2018 5:13 pm
by chong_zhou
My problem was resolved yesterday by a very simple approach. I would like to post it here in case others might have similar problem in the future.

To use zOS Unix socket, before including all necessary headers (i.e., sys/socket.h, netinet/in.h, and etc.), you have to tell the compiler which set of socket apis you want to use:

Berkeley or x/open.

You have to select one by defining a macro because there is no default one. Berkeley socket apis are said to be for compatibility purpose, so if you are writing new code, use x/open apis.

To use Berkeley socket:

#define _OE_SOCKETS
#including <sys/socket.h>
...
 


To use x/open socket:

#define _XOPEN_SOURCE_EXTENDED 1
#including <sys/socket.h>
...
 


To use getaddrinfo(), you have to set the 'level of posix c source':

#define _POSIX_C_SOURCE 200112L
#include <netdb.h>
...
 

Re: Using socket APIs in C program

PostPosted: Thu May 17, 2018 8:13 pm
by NicC
Thank you for posting your solution. I hope it can help others in the future.

Re: Using socket APIs in C program

PostPosted: Tue Feb 05, 2019 12:44 pm
by supriyala
Excellent topic. Great answers by experts. Thank you.

Re: Using socket APIs in C program

PostPosted: Tue Feb 19, 2019 10:07 am
by vijadhav321
Good information