Download presentation
Presentation is loading. Please wait.
Published byErika Smith Modified over 9 years ago
1
System Calls & Signals
2
setsockopt n Used to set socket options n SO_LINGER - Sets or gets the SO_LINGER option. The argument is a linger structure. n struct linger { n int l_onoff; /* linger active */ n int l_linger; /* how many seconds to linger for */ n }; When enabled, a close(2) or shutdown(2) will not return until all queued messages for the socket have been successfully sent or the linger timeout has been reached. int result; struct linger linger; linger.l_onoff = 1; /*0 = off (l_linger ignored), nonzero = on */ linger.l_linger =1; /* how many seconds to linger for */ result = setsockopt(s, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
3
Reuseaddr n Normally you have to wait for about 2 minutes to reuse the same port on a machine n This wait is intended to protect the TCP connection protocol from errors n You can override it with reuseaddr int optval = 1; setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); bind (s, &sin, sizeof(sin));
4
stat, fstat, lstat #include int stat(const char *pathname, struct stat *buf) int fstat(int fd, struct stat *buf) int lstat(const char *pathname, struct stat *buf)
5
stat int stat(const char *pathname, struct stat *buf) n Obtains information about the file pointed to by pathname. n Read, write or execute permission of the named file is not required, but all directories listed in the path name leading to the file must be searchable.
6
fstat int fstat(int fd, struct stat *buf) n Obtains the same information about an open file known by the file descriptor fd. int lstat(const char *pathname, struct stat *buf) n like stat() except in the case where the named file is a symbolic link, in which case lstat() returns information about the link, while stat() returns information about the file the link references.
7
struct stat Struct stat { mode_t st_mode;/* file type and mode (type & permissions) */ ino_t st_ino; /* inode’s number */ dev_t st_dev; /* device number (file system) */ nlink_t st_nlink; /* number of links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ off_t st_size; /* size in bytes */ time_t st_atime; /* last access */ time_t st_mtime; /* last modified */ time_t st_ctime; /* last file status change */ long st_blksize; /* I/O block size */ long st_blocks; /* number of blocks allocated */ }
8
HTTPD and Stat n You need to use stat in order to determine the type of a file, so you know whether to print out the directory if it doesn’t have a index.html file n You need to use stat to determine the content-length to send back on static files. int err = stat(fullpath, &fstats); if (err != 0) { logmessage = (char *)malloc(MAX_MSG_SZ); sprintf(logmessage,"Thread %d: [%s not found - replaced with %s]", threadnum, fullpath, gDocumentNotFoundPage); logQ->Enqueue(logmessage); // If the path is to a non-existent file, replace it with gDocumentNotFoundPage strcpy(fullpath, gDocumentNotFoundPage); sprintf(responseCode, "404 Document Not Found"); } if (fstats.st_mode & S_IFDIR) { AppendDefaultPage(fullpath, url); }
9
Signals n Introduced in UNIX systems to simplify IPC. n Used by the kernel to notify processes of system events. n A signal is a short message sent to a process, or group of processes, containing the number identifying the signal.
10
Example Signals n Linux supports 31 non-real-time signals. n POSIX standard defines a range of values for RT signals: SIGRTMIN 32 … SIGRTMAX (_NSIG-1) in
11
Signal Transmission n Signal sending: n Kernel updates descriptor of destination process. n Signal receiving: n Kernel forces target process to “handle” signal. n Pending signals are sent but not yet received. n Up to one pending signal per type for each process, except for POSIX.4 signals. n Subsequent signals are discarded. n Signals can be blocked, i.e., prevented from being received.
12
Signal-Related Data Structures n sa_handler specifies the action to be associated with signum. This function receives the signal number as its only argument. n sa_mask gives a mask of signals which should be blocked during execution of the signal handler n sa_flags specifies a set of flags which modify the behavior of the signal handling process (SA_RESTART) struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }
13
If you want more information siginfo_t { int si_signo; /* Signal number */ int si_errno; /* An errno value */ int si_code; /* Signal code */ pid_t si_pid; /* Sending process ID */ uid_t si_uid; /* Real user ID of sending process */ int si_status; /* Exit value or signal */ clock_t si_utime; /* User time consumed */ clock_t si_stime; /* System time consumed */ sigval_t si_value; /* Signal value */ int si_int; /* POSIX.1b signal */ void * si_ptr; /* POSIX.1b signal */ void * si_addr; /* Memory location which caused fault */ int si_band; /* Band event */ int si_fd; /* File descriptor */ }
14
Signal Handling System Calls n int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); Replaces the old signal() function. n Used to bind a handler to a signal. n Handler should match either n void handler(int); n void handler(int, siginfo_t *info, ucontext_t *uap); n The handler function should match this prototype if the SA_SIGINFO bit is set in flags. It then should be pointed to by the sa_sigaction member of struct sigaction.
15
#include void *functionC(void *ptr); void handler (int status); /* definition of signal handler */ int counter = 0; main() { int rc1, rc2; pthread_t thread1, thread2; // First set up the signal handler struct sigaction sigold, signew; signew.sa_handler=handler; sigemptyset(&signew.sa_mask); sigaddset(&signew.sa_mask,SIGINT); signew.sa_flags = SA_RESTART; sigaction(SIGINT,&signew,&sigold); /* Create independent threads each of which will execute functionC */ if( (rc1=pthread_create( &thread1, NULL, &functionC, (void *)1)) ) { printf("Thread creation failed: %d\n", rc1); } if( (rc2=pthread_create( &thread2, NULL, &functionC, (void *)2)) ) { printf("Thread creation failed: %d\n", rc2); } printf("I am parent thread %d[%u]\n", 0,(unsigned int)pthread_self()); pthread_join( thread1, NULL); pthread_join( thread2, NULL); } void handler (int status) { printf("%u received signal %d\n", (unsigned int)pthread_self(), status); } void *functionC(void *ptr) { int thnum = (int)ptr; for(;;) { sleep(1); counter++;// Note: This should be protected by semaphores printf("I am thread %d[%u] counter %d\n",thnum,(unsigned int)pthread_self(), counter); }
16
Signal Handlers n To get more information //void handler (int status, siginfo_t *info, ucontext_t *uap); void handler (int status, struct __siginfo *info, void *uap); ……. // First set up the signal handler struct sigaction sigold, signew; signew.sa_sigaction=handler; sigemptyset(&signew.sa_mask); sigaddset(&signew.sa_mask,SIGINT); signew.sa_flags = SA_RESTART | SA_SIGINFO; sigaction(SIGINT,&signew,&sigold); ……. //void handler (int status, siginfo_t *info, ucontext_t *uap) void handler (int status, struct __siginfo *info, void *uap) { printf("[%d]%u received signal %d from %d\n", getpid(), (unsigned int)pthread_self(), status, info->si_pid); }
17
Sending a Signal n int kill(pid_t pid, int sig); n Causes the signal to be delivered to another process n Example: n kill(pID,SIGKILL); n Signals are defined in /usr/include/sys/signal.h n Example usage: n kill the child you execed if it runs too long n How do we tell if a child runs too long?
18
Timers n int getitimer(int which, struct itimerval *value); n int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); n Provide microsecond granularity n Will send SIGALRM every interval struct itimerval { struct timeval it_interval; /* next value */ struct timeval it_value; /* current value */ }; struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ };
19
What have your kids been up to? n int getrusage(int who, struct rusage *usage); n Reports on resource usage by yourself and your children n Also set in n pid_t wait4(pid_t pid, int *stat_loc, int options, struct rusage *rusage); struct rusage { struct timeval ru_utime; /* user time used */ struct timeval ru_stime; /* system time used */ long ru_maxrss; /* maximum resident set size */ long ru_ixrss; /* integral shared memory size */ long ru_idrss; /* integral unshared data size */ long ru_isrss; /* integral unshared stack size */ long ru_minflt; /* page reclaims */ long ru_majflt; /* page faults */ long ru_nswap; /* swaps */ long ru_inblock; /* block input operations */ long ru_oublock; /* block output operations */ long ru_msgsnd; /* messages sent */ long ru_msgrcv; /* messages received */ long ru_nsignals; /* signals received */ long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary context switches */ };
20
#include using namespace std; void handler (int status); /* definition of signal handler */ // Global variable so signal handler can see it pid_t pID; // This example shows how to use execve and signals main() { struct sigaction sigold, signew; struct itimerval rttimer; struct itimerval old_rttimer; signew.sa_handler=handler; sigemptyset(&signew.sa_mask); sigaddset(&signew.sa_mask,SIGCHLD); sigaddset(&signew.sa_mask,SIGALRM); signew.sa_flags = SA_RESTART; sigaction(SIGCHLD,&signew,&sigold); sigaction(SIGALRM,&signew,&sigold); // Now set up the interval timer rttimer.it_value.tv_sec = 10; rttimer.it_value.tv_usec = 0; rttimer.it_interval.tv_sec = 10; rttimer.it_interval.tv_usec = 0; setitimer (ITIMER_REAL, &rttimer, &old_rttimer); pID = fork(); if (pID == 0) // child { // Code only executed by child process // exec the program char *argvToChild[5]; char *envToChild[5]; argvToChild[0] = "foo"; argvToChild[1] = "bar"; argvToChild[2] = NULL; envToChild[0] = "SERVER_NAME=gunga"; envToChild[1] = "GUMBO=GIMBO"; envToChild[2] = NULL; printf("Child about to exec\n"); execve("loop.pl",argvToChild,envToChild); perror("Child should not return"); } else // parent { // Code only executed by parent process for(;;); } void handler (int status) { int stat; int err; struct rusage child_ru; printf("received signal %d\n",status); if(status == SIGCHLD) { err = wait4(pID,&stat,0,&child_ru); printf("wait returned %d status %X exit status %d\n",err,stat, WEXITSTATUS(stat)); printf("user time %d, system time %d\n",child_ru.ru_utime.tv_sec,child_ru.ru_stime.tv_sec); } if(status == SIGALRM) { printf("This guy %d is toast\n",pID); kill(pID,SIGKILL); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.