My Wiki!

Socket

Basic socket programming

Select() - multiplexing

Handle Brocken pipe

socket level.. request level.. process level (handle signal).

SO_NOSIGPIPE

not available in Fedora 16. don't knwo why.

MSG_NOSIGNAL

Using send() with flag MSG_NOSIGNAL to prevent send() from emitting SIGPIPE in case peer broke dring writing. In that case, send() will return -1 and errno is set to EPIPE.

attention when using strerror(errno) to read errno, #include<string.h> must be available. Otherwise, client will crashed wit segfault.

Handle signal

static inline
void
suppress_sigpipe(void)
{
#if ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE)
  /*
We want to ignore possible SIGPIPE that we can generate on write.
SIGPIPE is delivered *synchronously* and *only* to the thread
doing the write. So if it is reported as already pending (which
means the thread blocks it), then we do nothing: if we generate
SIGPIPE, it will be merged with the pending one (there's no
queuing), and that suits us well. If it is not pending, we block
it in this thread (and we avoid changing signal action, because it
is per-process).
*/
  sigset_t pending;
  sigpending(&pending);
  control.sigpipe_pending = sigismember(&pending, SIGPIPE);
  if (! control.sigpipe_pending)
    {
      sigset_t blocked;
      pthread_sigmask(SIG_BLOCK, &config.sigpipe_mask, &blocked);

      /* Maybe is was blocked already? */
      control.sigpipe_unblock = ! sigismember(&blocked, SIGPIPE);
    }
#endif /* ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) */
}


static inline
void
restore_sigpipe(void)
{
#if ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE)
  /*
If SIGPIPE was pending already we do nothing. Otherwise, if it
become pending (i.e., we generated it), then we sigwait() it (thus
clearing pending status). Then we unblock SIGPIPE, but only if it
were us who blocked it.
*/
  if (! control.sigpipe_pending)
    {
      sigset_t pending;
      sigpending(&pending);
      if (sigismember(&pending, SIGPIPE))
        {
          /*
Protect ourselves from a situation when SIGPIPE was sent
by the user to the whole process, and was delivered to
other thread before we had a chance to wait for it.
*/
          static const struct timespec nowait = { 0, 0 };
          RESTART(sigtimedwait(&config.sigpipe_mask, NULL, &nowait));
        }

      if (control.sigpipe_unblock)
        pthread_sigmask(SIG_UNBLOCK, &config.sigpipe_mask, NULL);
    }
#endif /* ! defined(MSG_NOSIGNAL) && ! defined(SO_NOSIGPIPE) */
}

Useful linux command

child/parent processes

  • ps aux | grep
  • pstree
  • ps –ppid <parentprocessid>
  • ps –forest -ef

socket info

  • ipcs
  • netstat -vaun see open ports & processes
  • lsof -i display list of open ports
  • lsof -i 4 -a -p 9255 display all open IPv4 network files in use by the process whose PID is 9255

Sources

Portable Socket

cpp socket

Sources


Navigation