Strange "getsockopt" Solaris behavior


 
Thread Tools Search this Thread
Top Forums Programming Strange "getsockopt" Solaris behavior
# 1  
Old 01-18-2015
Hammer & Screwdriver Strange "getsockopt" Solaris behavior

Please take a look on following code:

Code:
    s = socket(PF_INET, SOCK_STREAM, 0);    //socket
    fcntl(s, F_SETFL, O_NONBLOCK);             //set socket to nonblock

retry_conn:    
    ret = connect(s, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in)); // try to connect, for sure there no connection to "serv_addr" 
    printf("connect, status=%d, errno=%d \n", status, errno); 
    
    if (errno == EINPROGRESS) //no connection
    {
        if (poll(fds, 1, delay_time / 1000) > 0)
        {
            ret = getsockopt(s, SOL_SOCKET, SO_ERROR, &error_s, &len_s)
            printf("getsockopt, status: %d, error_s=%d, errno=%d\n", status, error_s, errno);
        }
        
        if (error_s)
        {
            printf("try_connect_again\n");
            goto: try_connect_again;
        }
        else
        {
            connected!!!!!!!!!
        }
    }

And now, what is the problem. When "connect" is executed for the first time (return code = 150), "getsockopt" in "error_s" return code "146", but after "goto"
when "getsockopt" is executed second time "error_s" is equal "0" (which means connection is established successfully).

Example output:

Code:
    connect, status=-1, errno=150
    getsockopt, status: 0, error_s=146, errno=150
    try_connect_again
    connect, status=-1, errno=150
    getsockopt, status: 0, error_s=0, errno=0

The same code executed on i.e. Linux CentOS or HPUX, when getsockopt is executed second time, return error codes and inform that there is no connection but in case of Solaris
"getsockopt" works in a strange way.

Please explain what is the problem or how to deal with such behavior on Solaris.

Thanks in advance.

Last edited by revolta25; 01-19-2015 at 03:12 AM..
# 2  
Old 01-18-2015
Your sample output does not match what the code you posted would emit. There's no "try connect again!" in your sample output, yet your code would have printed that given the value of errno_s.

Not only that, your code would not compile as the else clause following the goto statement is not valid C or C++ code.

It's hard to know what's going on when the code you post can not produce the output you're seeing.

Also, why are you assuming errno will be reset to zero? Few if any library calls will do that, especially on Solaris, which follows POSIX and other specifications MUCH more closely than Linux does.
# 3  
Old 01-18-2015
In addition to what achenle has already said:
  1. you are missing a ; after the call to getsockopt(),
  2. there is no : in a goto statement, and
  3. there is no label try_connect_again.
# 4  
Old 01-19-2015
Quote:
Originally Posted by achenle
Your sample output does not match what the code you posted would emit. There's no "try connect again!" in your sample output, yet your code would have printed that given the value of errno_s.

Not only that, your code would not compile as the else clause following the goto statement is not valid C or C++ code.

It's hard to know what's going on when the code you post can not produce the output you're seeing.

Also, why are you assuming errno will be reset to zero? Few if any library calls will do that, especially on Solaris, which follows POSIX and other specifications MUCH more closely than Linux does.
Quote:
Originally Posted by Don Cragun
In addition to what achenle has already said:

you are missing a ; after the call to getsockopt(),
there is no : in a goto statement, and
there is no label try_connect_again.
It is just a pseudo-code - to show what is the main problem.

connect -> poll -> getsockopt (return errno_s = 146 - correct) -> connect -> poll -> getsockopt (return errno_s = 0)

When "getsockopt" is executed second time, for some reason "optval" (errno_s) is equal "0".
# 5  
Old 01-19-2015
OK. So you showed us imaginary output from pseudo-code that won't compile and has never been run. That makes it hard for us to imagine what problems you might run into if you wrote working code and actually looked at the output it might produce.

If you have code that did produce the output you showed us, show us that code! If not, write some code, compile it, run it, and show us the code and the output that was produced by running that code.

We see nothing at all strange about the output produced by getsockopt() on a Solaris system from the pseudo-code you've shown us. If we don't know what you passed to getsockopt(), we can't guess at what any OS might do with the data it was given.
# 6  
Old 01-19-2015
First, thanks for your interest

Code:
#include <assert.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/devpoll.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <sys/socket.h>
#include <netinet/tcp.h>

int main()
{
    int fd = -1;
    int ret = 0;
    int error_s = 0;
    struct sockaddr_in serv_addr;
    int delay_time = 3000;
    int len_s = sizeof(int);
    int try = 3;
    
    fd = socket(PF_INET, SOCK_STREAM, 0);
    fcntl(fd, F_SETFL, O_NONBLOCK);
    printf("fd=\"%d\" \n", fd);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(45678);
    serv_addr.sin_addr.s_addr = inet_addr("10.0.0.5");
    
try_connect_again:

    printf("try_connect_again\n");
    printf("attempt left %d ...\n", try);
    if (!try)
        goto fin;
        
    usleep(2000);
    ret = connect(fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in));
    printf("connect ret=%d, errno=%d\n", ret, errno);
    
    if (errno == EINPROGRESS)
    {
        do
        {
            struct pollfd fds;

            fds.fd = fd;
            fds.events = POLLIN | POLLOUT;
            ret = poll(&fds, 1, delay_time);
            
            if (ret == -1) //poll error
            {
                goto fin;
            }
        }
        while (!ret);
        
        if (ret)
        {
            ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error_s, &len_s);
            printf("getsockopt, ret=%d, error_s=%d \n", ret, error_s);
            if (error_s == 0)
                printf("connected\n");
            else
            {
                try--;
                goto try_connect_again;
            }
        }
        else if (ret == 0)
        {
            try--;
            goto try_connect_again;
        }
    }

fin:
    printf("end\n");
    return 0;
}

gcc -lsocket -lresolv -lnsl -g -o test1 test1.c

Above code generate following output:

Quote:
fd="3"
try_connect_again
attempt left 3 ...
connect ret=-1, errno=150
getsockopt, ret=0, error_s=146
try_connect_again
attempt left 2 ...
connect ret=-1, errno=150
getsockopt, ret=0, error_s=0
I can't find the reason, why getsockopt works different during second attempt.
# 7  
Old 01-19-2015
Add a printf() to show what poll() returns...
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Bash script - Print an ascii file using specific font "Latin Modern Mono 12" "regular" "9"

Hello. System : opensuse leap 42.3 I have a bash script that build a text file. I would like the last command doing : print_cmd -o page-left=43 -o page-right=22 -o page-top=28 -o page-bottom=43 -o font=LatinModernMono12:regular:9 some_file.txt where : print_cmd ::= some printing... (1 Reply)
Discussion started by: jcdole
1 Replies

2. Shell Programming and Scripting

Why awk print is strange when I set FS = " " instead of FS = "\t"?

Look at the following data file(cou.data) which has four fields separated by tab. Four fields are country name, land area, population, continent where it belongs. As for country name or continent name which has two words, two words are separated by space. (Data are not accurately... (1 Reply)
Discussion started by: chihuyu
1 Replies

3. Shell Programming and Scripting

Weird behavior of command "local"

Hi there, I'm running into a very weird situation. Let's forget about the purpose of my initial script please. I noticed the bug whatever I'm trying to do. I'm on an old server running bash 3.1.17. Say we have the following script : foo:~# cat /tmp/test #!/bin/bash f1() { local... (9 Replies)
Discussion started by: chebarbudo
9 Replies

4. Shell Programming and Scripting

Commenting out "expr" creates weird behavior

This really puzzles me. The following code gives me the error 'expr: syntax error' when I try to do multi-line comment using here document <<EOF echo "Sum is: `expr $1 + $2`" EOF Even if I explicitly comment out the line containing the expr using "#", the error message would still exist... (3 Replies)
Discussion started by: royalibrahim
3 Replies

5. Solaris

Printer configuration Migration from Solaris 10 "LP" to Solaris 11 "CUPS"

Need to find a way to import an LP printers.conf file to CUPS. I have some new Solaris 11.1 boxes that need to have 300 printers added. (0 Replies)
Discussion started by: os2mac
0 Replies

6. UNIX for Advanced & Expert Users

"╭─ " Character combo in $PATH causes strange autocompletion behavior in zsh

I've posted about this before, but only recently narrowed the problem down to a specific cause. Ok, first of all, the behavior: It occurs when autocompletion brings up its list (not when there is only a single option). Basically, if I were to type, say, cd ~/<TAB> I would get something... (2 Replies)
Discussion started by: marshaul
2 Replies

7. Shell Programming and Scripting

awk command to replace ";" with "|" and ""|" at diferent places in line of file

Hi, I have line in input file as below: 3G_CENTRAL;INDONESIA_(M)_TELKOMSEL;SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL My expected output for line in the file must be : "1-Radon1-cMOC_deg"|"LDIndex"|"3G_CENTRAL|INDONESIA_(M)_TELKOMSEL"|LAST|"SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL" Can someone... (7 Replies)
Discussion started by: shis100
7 Replies

8. Shell Programming and Scripting

"Odd" behavior exiting shell script

Is it normal behavior for a shell script that terminates to terminate its parent shell when executed with the "." option? For example, if I have the example script (we'll name it ex.sh): #!/bin/sh if then echo "Bye." exit 2 fi And I execute it like this: >./ex.sh It... (6 Replies)
Discussion started by: DreamWarrior
6 Replies

9. Solaris

Solaris escape my script from "-" to "/226"

Hello everyone. I beg your guys pardon please. I try to ls -al in many path/directories. So, I put the code in text file which look like below; ls -al / ls -al /etc ls -al /etc/default ... however, when I paste it to Solaris over SecureCRT, it seems the code was escaped from "-" to... (0 Replies)
Discussion started by: Smith
0 Replies

10. Shell Programming and Scripting

[Perl] Strange ne "NO" behavior.

Hi there, I have a strange problem and I cannot figure it out what I am doing wrong here. Let me try to picture it. In principle it is prety straight forward, but something odd is happening. Here is part of the input file snmp_alm.cfg: ... (2 Replies)
Discussion started by: ejdv
2 Replies
Login or Register to Ask a Question