Table of Contents
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
- layer 2,3 sockets: http://aschauf.landshut.org/fh/linux/udp_vs_raw/ch01.html
- message handling:
- sending struct over network:
Portable Socket
cpp socket