connect() returns ESPIPE

  • Follow


Hello, All!

How it can turn out that connect() returns -1 and sets up 'errno' to ESPIPE?
I'm confused because 'man connect' doesn't mention of such result.

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply Roman 8/1/2005 10:54:42 AM

"Roman Mashak" <mrv@tusur.ru> writes:
> How it can turn out that connect() returns -1 and sets up 'errno' to ESPIPE?
> I'm confused because 'man connect' doesn't mention of such result.

Show us a minimal, compilable program that exhibits the problem.
0
Reply Giorgos 8/1/2005 11:35:33 AM


Hello, Giorgos!
You wrote  on 01 Aug 2005 14:35:33 +0300:

 ??>> How it can turn out that connect() returns -1 and sets up 'errno' to
 ??>> ESPIPE? I'm confused because 'man connect' doesn't mention of such
 ??>> result.

 GK> Show us a minimal, compilable program that exhibits the problem.
This one gives behavior described above when 'server-side' is down (i.e. not 
running):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>

#define PORT 5000
#define HOST "127.0.0.1"

int main(int argc, char *argv[], char *envp[])
{
  int sd;     /* socket descriptor */
  struct sockaddr_in serv_addr;
  struct hostent *hp;

  /* get network host entry */
  if ( (hp = gethostbyname(HOST)) == 0 ) {
   perror("gethostbyname() error");
   exit(1);
  }

  /* zero out structure */
  memset(&serv_addr, 0, sizeof serv_addr);

  /* fill in structure */
  serv_addr.sin_family = AF_INET;
  memcpy(&serv_addr.sin_addr, hp->h_addr, hp->h_length);
  serv_addr.sin_port = htons(PORT);

  /* create socket based on TCP */
  if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
    perror("socket() error!");
    exit(1);
  }

  fprintf(stdout, "Server address: %s\n", inet_ntoa(serv_addr.sin_addr));

  /* create virtual link */
  if ( connect(sd, (struct sockaddr *)&serv_addr, sizeof serv_addr) == -1 ) 
{
   perror("connect() error");
   printf("errno=%d\n",errno);
   //if ( errno == ECONNREFUSED || errno == ENETUNREACH )
    //print_html_response(NETWORK_ERR);
   //free(cq);
   exit(1);
  }

  ....

  close(sd);

  return 0;
}

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply Roman 8/1/2005 11:51:53 AM

Roman Mashak wrote:

>   /* create virtual link */
>   if ( connect(sd, (struct sockaddr *)&serv_addr, sizeof serv_addr) == -1 ) 
> {
      int tmp=errno;
>    perror("connect() error");
>    printf("errno=%d\n", errno);
      printf("tmperr=%d\n", tmp);

perror has probably changed/reset errno in between.
use a temp.


>    //if ( errno == ECONNREFUSED || errno == ENETUNREACH )
>     //print_html_response(NETWORK_ERR);
>    //free(cq);
>    exit(1);
>   }
> 
>   ....
> 
>   close(sd);
> 
>   return 0;
> }
> 
> With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 
> 
> 

HTH,
AvK
0
Reply moi 8/1/2005 12:08:19 PM

moi wrote:
> Roman Mashak wrote:
> 
>>   /* create virtual link */
>>   if ( connect(sd, (struct sockaddr *)&serv_addr, sizeof serv_addr) == 
>> -1 ) {
> 
>      int tmp=errno;
> 
>>    perror("connect() error");
>>    printf("errno=%d\n", errno);
> 
>      printf("tmperr=%d\n", tmp);
> 
> perror has probably changed/reset errno in between.
> use a temp.
> 
> 
>>    //if ( errno == ECONNREFUSED || errno == ENETUNREACH )
>>     //print_html_response(NETWORK_ERR);
>>    //free(cq);
>>    exit(1);
>>   }
>>
>>   ....
>>
>>   close(sd);
>>
>>   return 0;
>> }
>>
>> With best regards, Roman Mashak.  E-mail: mrv@tusur.ru
>>
> 
> HTH,
> AvK

Sorry, perror() probably doesn't return, but calls exit() instead.
please ignore.

AvK
0
Reply moi 8/1/2005 12:13:17 PM

Roman Mashak wrote:

>  ??>> How it can turn out that connect() returns -1 and sets up 'errno' to
>  ??>> ESPIPE? I'm confused because 'man connect' doesn't mention of such
>  ??>> result.

>    perror("connect() error");
>    printf("errno=%d\n",errno);

perror() screws up errno. Use instead:

   int e = errno; // e == 111 == ECONNREFUSED
   perror("connect() error"); 
   printf("errno=%d\n", e);

0
Reply Maxim 8/1/2005 12:49:09 PM

moi wrote:

[]

> Sorry, perror() probably doesn't return, but calls exit() instead.

It does not call exit(), it does return.

0
Reply Maxim 8/1/2005 1:03:48 PM

Hello, Maxim!
You wrote  on 1 Aug 2005 05:49:09 -0700:

 ??>>>> ESPIPE? I'm confused because 'man connect' doesn't mention of such
 ??>>>> result.

 ??>>    perror("connect() error");
 ??>>    printf("errno=%d\n",errno);

 MY> perror() screws up errno. Use instead:
Thanks, 'man perror' is my friend ;)
BTW, right now I'm checking 'connect()' return status for ECONNREFUSED or 
ENETUNREACH. Is it enough to make sure the connection failed due to link 
reasons (like, network problems, remote peer down etc.) ?

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply Roman 8/1/2005 1:07:25 PM

Roman Mashak wrote:

[]

> BTW, right now I'm checking 'connect()' return status for ECONNREFUSED or
> ENETUNREACH. Is it enough to make sure the connection failed due to link
> reasons (like, network problems, remote peer down etc.) ?

Probably much easier to check for success. For nonblocking socket:

    if(connect(s, (sockaddr*)&sa, sizeof(sa)) && errno != EINPROGRESS)
       // error

0
Reply Maxim 8/1/2005 1:26:14 PM

moi <avk@localhost> writes:
>moi wrote:
>> Roman Mashak wrote:
>>>   /* create virtual link */
>>>   if ( connect(sd, (struct sockaddr *)&serv_addr, sizeof serv_addr) == -1 ) {
>>      int tmp=errno;
>>
>>>    perror("connect() error");
>>>    printf("errno=%d\n", errno);
>>
>> perror has probably changed/reset errno in between.
>> use a temp.
>
> Sorry, perror() probably doesn't return, but calls exit() instead.
> please ignore.

No, it doesn't.
0
Reply Giorgos 8/1/2005 1:36:08 PM

"Roman Mashak" <mrv@tusur.ru> writes:
> Hello, Giorgos!
> You wrote  on 01 Aug 2005 14:35:33 +0300:
>
>  ??>> How it can turn out that connect() returns -1 and sets up 'errno' to
>  ??>> ESPIPE? I'm confused because 'man connect' doesn't mention of such
>  ??>> result.
>
>  GK> Show us a minimal, compilable program that exhibits the problem.
>
> This one gives behavior described above when 'server-side' is down
> (i.e. not running):

> [program source snipped]

I'm not seeing ESPIPE here:

% beatrix:/tmp/foo$ ./a.out
% Server address: 127.0.0.1
% connect() error: Connection refused
% errno=146
% beatrix:/tmp/foo$ grep 146 /usr/include/sys/errno.h
% #define ECONNREFUSED    146     /* Connection refused */
% beatrix:/tmp/foo$

0
Reply Giorgos 8/1/2005 1:40:01 PM

Hello, Maxim!
You wrote  on 1 Aug 2005 06:26:14 -0700:

 MY> []

 ??>> BTW, right now I'm checking 'connect()' return status for ECONNREFUSED
 ??>> or ENETUNREACH. Is it enough to make sure the connection failed due to
 ??>> link reasons (like, network problems, remote peer down etc.) ?

 MY> Probably much easier to check for success. For nonblocking socket:
 MY>  if(connect(s, (sockaddr*)&sa, sizeof(sa)) && errno != EINPROGRESS)
Hm.. I guess if 'connect()' is succesfull (i.e. != -1) then 'errno' isn't 
set at all.

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply Roman 8/2/2005 12:33:38 AM

In article <dcmf4n$2u03$1@relay.tomsk.ru>,
 "Roman Mashak" <mrv@tusur.ru> wrote:

> Hello, Maxim!
> You wrote  on 1 Aug 2005 06:26:14 -0700:
> 
>  MY> []
> 
>  ??>> BTW, right now I'm checking 'connect()' return status for ECONNREFUSED
>  ??>> or ENETUNREACH. Is it enough to make sure the connection failed due to
>  ??>> link reasons (like, network problems, remote peer down etc.) ?
> 
>  MY> Probably much easier to check for success. For nonblocking socket:
>  MY>  if(connect(s, (sockaddr*)&sa, sizeof(sa)) && errno != EINPROGRESS)
> Hm.. I guess if 'connect()' is succesfull (i.e. != -1) then 'errno' isn't 
> set at all.

That's true for pretty much all system calls.  errno is only meaningful 
if the call returns an indication that it failed.  If it succeeds, errno 
is supposed to be left unchanged.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
0
Reply Barry 8/2/2005 5:45:24 AM

Roman Mashak wrote:

[]

>  MY> Probably much easier to check for success. For nonblocking socket:
>  MY>  if(connect(s, (sockaddr*)&sa, sizeof(sa)) && errno != EINPROGRESS)
> Hm.. I guess if 'connect()' is succesfull (i.e. != -1) then 'errno' isn't
> set at all.

So, what's the problem? Here errno is checked only when connect()
returns non zero value.

0
Reply Maxim 8/2/2005 6:20:51 AM

Hello, Maxim!
You wrote  on 1 Aug 2005 23:20:51 -0700:

 MY> []

 MY>>> Probably much easier to check for success. For nonblocking socket:
 MY>>>  if(connect(s, (sockaddr*)&sa, sizeof(sa)) && errno != EINPROGRESS)
 ??>> Hm.. I guess if 'connect()' is succesfull (i.e. != -1) then 'errno'
 ??>> isn't set at all.
MY> So, what's the problem? Here errno is checked only when connect()
MY> returns non zero value.
I think here is some logical problem :)  because if (connect(...) ) will be 
true only when 'connect()' returns 1 and it's the only condition to match 
with second checking (errno !=EINPROGRESS)

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply Roman 8/2/2005 6:42:53 AM

Roman Mashak wrote:
> Hello, Maxim!
> You wrote  on 1 Aug 2005 23:20:51 -0700:
>
>  MY> []
>
>  MY>>> Probably much easier to check for success. For nonblocking socket:
>  MY>>>  if(connect(s, (sockaddr*)&sa, sizeof(sa)) && errno != EINPROGRESS)
>  ??>> Hm.. I guess if 'connect()' is succesfull (i.e. != -1) then 'errno'
>  ??>> isn't set at all.
> MY> So, what's the problem? Here errno is checked only when connect()
> MY> returns non zero value.
> I think here is some logical problem :)  because if (connect(...) ) will be
> true only when 'connect()' returns 1 and it's the only condition to match
> with second checking (errno !=EINPROGRESS)

You are wrong. You might like to get a C/C++ textbook.

connect() may return only 0 and -1. if(x) is true for any value but
zero. So, the check:

   int err = connect(s, (sockaddr*)&sa, sizeof(sa)) && errno !=
EINPROGRESS;

yields 1 only if connect() returned non zero and the error is not
EINPROGRESS.

0
Reply Maxim 8/2/2005 8:52:38 AM

On Mon, 01 Aug 2005 14:08:19 +0200,
    moi <avk@localhost> wrote:


> Roman Mashak wrote:
>
>>   /* create virtual link */
>>   if ( connect(sd, (struct sockaddr *)&serv_addr, sizeof serv_addr) == -1 ) 
>> {
>       int tmp=errno;
>>    perror("connect() error");
>>    printf("errno=%d\n", errno);
>       printf("tmperr=%d\n", tmp);
>
> perror has probably changed/reset errno in between.
> use a temp.
>

Anything calling stdio functions, including perror is quite likely
to set errno to ESPIPE without otherwise failing.  This comes from
the stdio library calling lseek() behind your back. This is very
noticable on linux systems if you run the program with strace.  If
perror didn't do it, then for sure printf would do it.

Villy
0
Reply Villy 8/2/2005 9:03:51 AM

Hello, Maxim!
You wrote  on 2 Aug 2005 01:52:38 -0700:

 MY> connect() may return only 0 and -1. if(x) is true for any value but
 MY> zero. So, the check:

 MY>    int err = connect(s, (sockaddr*)&sa, sizeof(sa)) && errno !=
 MY> EINPROGRESS;
exactly, my mistake!

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply Roman 8/2/2005 9:51:35 AM

> That's true for pretty much all system calls.  errno is only
> meaningful if the call returns an indication that it failed.  If it
> succeeds, errno is supposed to be left unchanged.

It would be more accurate to say: "If it succeeds, errno can be set
equal to any random value, and therefore should not be examined."

b
0
Reply blr 8/5/2005 5:59:27 AM

In article <dcuv7v$eqe$1@drizzle.com>, blr@drizzle.com (Brian Raiter) 
wrote:

> > That's true for pretty much all system calls.  errno is only
> > meaningful if the call returns an indication that it failed.  If it
> > succeeds, errno is supposed to be left unchanged.
> 
> It would be more accurate to say: "If it succeeds, errno can be set
> equal to any random value, and therefore should not be examined."

Maybe I'm misremembering, but I thought system calls were required to 
leave errno unchanged.  However, library functions are not so 
constrained.  They're likely to make system calls internally, and some 
of these system calls could fail even though the library call is 
eventually successful; typical implementations of isatty() work by 
performing an ioctl() that fails unless the fd is connected to a 
terminal.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
0
Reply Barry 8/6/2005 2:10:27 AM

>>> That's true for pretty much all system calls.  errno is only
>>> meaningful if the call returns an indication that it failed.  If
>>> it succeeds, errno is supposed to be left unchanged.
>> 
>> It would be more accurate to say: "If it succeeds, errno can be set
>> equal to any random value, and therefore should not be examined."
>
> Maybe I'm misremembering, but I thought system calls were required
> to leave errno unchanged. However, library functions are not so
> constrained.

I misread your original post, substituting "library" for "system". So,
never mind. (Although I have no idea if system calls are actually
*required* to preserve errno, or if they just generally happen to.)

b
0
Reply blr 8/9/2005 6:33:31 PM

20 Replies
361 Views

(page loaded in 0.244 seconds)

Similiar Articles:










7/23/2012 12:20:03 PM


Reply: