Initial commit
This commit is contained in:
108
kapitel17/daemon-ex2.c
Normal file
108
kapitel17/daemon-ex2.c
Normal file
@@ -0,0 +1,108 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
void sigHandler(int sig);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t process_id = 0;
|
||||
pid_t sid = 0;
|
||||
FILE *fp;
|
||||
char pidfile[] = "/tmp/daemon-sig-ex.pid";
|
||||
/* Skapa barn/child process */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Avsluta förälderprocessen */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Starta en ny session */
|
||||
sid = setsid();
|
||||
if(sid < 0)
|
||||
{
|
||||
/* Avsluta ifall det inte gick att skapa en ny
|
||||
session */
|
||||
fprintf(stderr, "Misslyckades att skapa en ny session\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Gör en ny fork för att förhindra att demonen kan bli en
|
||||
sessionsledare */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Avsluta föräldern den eftersom allt arbete kommer att
|
||||
utföras av demonen. Skriv också demonens PID-fil */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
printf("Demonens PID: %d \n", process_id);
|
||||
fp = fopen(pidfile, "w");
|
||||
fprintf(fp, "%d", process_id);
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
/* Sätt umask till 022 (rw-r--r-- / rwx-r-xr-x) */
|
||||
umask(022);
|
||||
|
||||
/* Ändra aktuell katalog till / */
|
||||
chdir("/");
|
||||
|
||||
/* Stäng stdin, stdout och stderr och återöppna dem
|
||||
till /dev/null */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
open("/dev/null", O_RDONLY); /* 0 = stdin */
|
||||
open("/dev/null", O_WRONLY); /* 1 = stdout */
|
||||
open("/dev/null", O_RDWR); /* 2 = stderr */
|
||||
|
||||
/* Registrera signalhanterarna, en för varje signal
|
||||
som vi vill fånga upp */
|
||||
signal(SIGUSR1, sigHandler);
|
||||
signal(SIGTERM, sigHandler);
|
||||
/* Demonens arbete... */
|
||||
for(;;)
|
||||
{
|
||||
sleep(5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sigHandler(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1)
|
||||
{
|
||||
/* Skriv till syslog-demonen */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGUSR1");
|
||||
}
|
||||
else if (sig == SIGTERM)
|
||||
{
|
||||
/* Samma som ovan */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGTERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_DAEMON, "Någonting hände med demonen...");
|
||||
}
|
||||
/* Signalhanteraren återställs efter första signalen,
|
||||
vi måste därför sätta den igen */
|
||||
signal(sig, sigHandler);
|
||||
}
|
106
kapitel17/daemon-sig-ex1.c
Normal file
106
kapitel17/daemon-sig-ex1.c
Normal file
@@ -0,0 +1,106 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
void sigHandler(int sig);
|
||||
int main(void)
|
||||
{
|
||||
pid_t process_id = 0;
|
||||
pid_t sid = 0;
|
||||
FILE *fp;
|
||||
char pidfile[] = "/tmp/daemon-sig-ex.pid";
|
||||
/* Skapa barn/child process */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Avsluta förälderprocessen */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Starta en ny session */
|
||||
sid = setsid();
|
||||
if(sid < 0)
|
||||
{
|
||||
/* Avsluta ifall det inte gick att skapa en ny
|
||||
session */
|
||||
fprintf(stderr, "Misslyckades att skapa en ny session\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Gör en ny fork för att förhindra att demonen kan bli en
|
||||
sessionsledare */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Avsluta föräldern den eftersom allt arbete kommer att
|
||||
utföras av demonen. Skriv också demonens PID-fil */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
printf("Demonens PID: %d \n", process_id);
|
||||
fp = fopen(pidfile, "w");
|
||||
fprintf(fp, "%d", process_id);
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
/* Sätt umask till 022 (rw-r--r-- / rwx-r-xr-x) */
|
||||
umask(022);
|
||||
|
||||
/* Ändra aktuell katalog till / */
|
||||
chdir("/");
|
||||
|
||||
/* Stäng stdin, stdout och stderr och återöppna dem
|
||||
till /dev/null */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
open("/dev/null", O_RDONLY); /* 0 = stdin */
|
||||
open("/dev/null", O_WRONLY); /* 1 = stdout */
|
||||
open("/dev/null", O_RDWR); /* 2 = stderr */
|
||||
|
||||
/* Registrera signalhanterarna, en för varje signal
|
||||
som vi vill fånga upp */
|
||||
signal(SIGUSR1, sigHandler);
|
||||
signal(SIGTERM, sigHandler);
|
||||
/* Demonens arbete... */
|
||||
for(;;)
|
||||
{
|
||||
sleep(5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sigHandler(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1)
|
||||
{
|
||||
/* Skriv till syslog-demonen */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGUSR1");
|
||||
}
|
||||
else if (sig == SIGTERM)
|
||||
{
|
||||
/* Samma som ovan */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGTERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_DAEMON, "Någonting hände med demonen...");
|
||||
}
|
||||
/* Signalhanteraren återställs efter första signalen,
|
||||
vi måste därför sätta den igen */
|
||||
signal(sig, sigHandler);
|
||||
}
|
125
kapitel17/daemon-sig-ex2.c
Normal file
125
kapitel17/daemon-sig-ex2.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
char pidfile[] = "/tmp/daemon-sig-ex.pid";
|
||||
|
||||
void sigHandler(int sig);
|
||||
void shutDown(int sig);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t process_id = 0;
|
||||
pid_t sid = 0;
|
||||
FILE *fp;
|
||||
/* Skapa barn/child process */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Avsluta förälderprocessen */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Starta en ny session */
|
||||
sid = setsid();
|
||||
|
||||
if(sid < 0)
|
||||
{
|
||||
/* Avsluta ifall det inte gick att skapa en ny
|
||||
session */
|
||||
fprintf(stderr, "Misslyckades att skapa en ny session\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Gör en ny fork för att förhindra att demonen kan bli en
|
||||
sessionsledare */
|
||||
process_id = fork();
|
||||
|
||||
/* Hantera eventuellt fel vid fork() */
|
||||
if (process_id < 0)
|
||||
{
|
||||
fprintf(stderr, "fork misslyckades!\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Avsluta föräldern den eftersom allt arbete kommer att
|
||||
utföras av demonen. Skriv också demonens PID-fil */
|
||||
else if (process_id > 0)
|
||||
{
|
||||
printf("Demonens PID: %d \n", process_id);
|
||||
fp = fopen(pidfile, "w");
|
||||
fprintf(fp, "%d", process_id);
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Sätt umask till 022 (rw-r--r-- / rwx-r-xr-x) */
|
||||
umask(022);
|
||||
|
||||
/* Ändra aktuell katalog till / */
|
||||
chdir("/");
|
||||
|
||||
/* Stäng stdin, stdout och stderr. Dessa behövs inte
|
||||
i en demonprocess */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
open("/dev/null", O_RDONLY); /* 0 = stdin */
|
||||
open("/dev/null", O_WRONLY); /* 1 = stdout */
|
||||
open("/dev/null", O_RDWR); /* 2 = stderr */
|
||||
|
||||
/* Registrera signalhanterarna, en för varje signal
|
||||
som vi vill fånga upp */
|
||||
signal(SIGUSR1, sigHandler);
|
||||
signal(SIGTERM, sigHandler);
|
||||
signal(SIGABRT, shutDown);
|
||||
signal(SIGQUIT, shutDown);
|
||||
signal(SIGINT, shutDown);
|
||||
|
||||
/* Demonens arbete... */
|
||||
for(;;)
|
||||
{
|
||||
sleep(5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sigHandler(int sig)
|
||||
{
|
||||
if (sig == SIGUSR1)
|
||||
{
|
||||
/* Skriv till syslog-demonen */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGUSR1");
|
||||
}
|
||||
else if (sig == SIGTERM)
|
||||
{
|
||||
/* Samma som ovan */
|
||||
syslog(LOG_DAEMON, "Tog emot SIGTERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_DAEMON, "Någonting hände med demonen...");
|
||||
}
|
||||
/* Signalhanteraren återställs efter första signalen,
|
||||
vi måste därför sätta den igen */
|
||||
signal(sig, sigHandler);
|
||||
}
|
||||
|
||||
void shutDown(int sig)
|
||||
{
|
||||
syslog(LOG_DAEMON, "Demonen avslutas");
|
||||
/* Ta bort PID-filen */
|
||||
if ( unlink(pidfile) == -1 )
|
||||
syslog(LOG_DAEMON, "Kunde inte ta bort PID-filen");
|
||||
exit(0);
|
||||
}
|
20
kapitel17/fifo-client-ex1.c
Normal file
20
kapitel17/fifo-client-ex1.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define FIFONAM "/tmp/testfifo"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
FILE *fp;
|
||||
signed char c;
|
||||
if ( access(FIFONAM, R_OK) != 0 )
|
||||
{
|
||||
fprintf(stderr, "Problem att öppna %s\n", FIFONAM);
|
||||
return 1;
|
||||
}
|
||||
fp = fopen(FIFONAM, "r");
|
||||
while ((c = getc(fp)) != EOF)
|
||||
putchar(c);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
79
kapitel17/fifo-ex1.c
Normal file
79
kapitel17/fifo-ex1.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FIFONAM "/tmp/testfifo"
|
||||
|
||||
/* Skapa fifofd i det globala scopet så att
|
||||
vi kan stänga den ifrån signalhanteraren. */
|
||||
int fifofd;
|
||||
|
||||
void cleanUp(int signum);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char msg[] = "Ett meddelande till klienterna\n";
|
||||
|
||||
/* Registrera signalhanterare för vanliga "avsluts-signaler" */
|
||||
signal(SIGINT, cleanUp);
|
||||
signal(SIGQUIT, cleanUp);
|
||||
signal(SIGABRT, cleanUp);
|
||||
signal(SIGTERM, cleanUp);
|
||||
/* Ignorera SIGPIPE, annars avslutas programmet när
|
||||
mottagaren stängs */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/* Skapa FIFOn. S_IWUSR och S_IRUSR är detsamma som för
|
||||
open() och creat() */
|
||||
if ( mkfifo(FIFONAM, S_IWUSR | S_IRUSR) != 0)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
{
|
||||
fprintf(stderr, "FIFOn finns redan, använder den\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("mkfifo");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Öppna FIFOn */
|
||||
fifofd = open(FIFONAM, O_WRONLY);
|
||||
if (fifofd < 0)
|
||||
{
|
||||
perror("open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Skriv meddelanden i en oändlig loop */
|
||||
while(1)
|
||||
{
|
||||
write(fifofd, msg, sizeof(msg));
|
||||
sleep(1); /* Vänta en sekund mellan varje körning */
|
||||
}
|
||||
/* Hit bör vi aldrig komma, men fall i fall så städar vi upp */
|
||||
unlink(FIFONAM);
|
||||
close(fifofd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanUp(int signum)
|
||||
{
|
||||
/* Stäng fildeskriptorn */
|
||||
if ( close(fifofd) == -1 )
|
||||
perror("cleanUp - close");
|
||||
|
||||
/* Radera FIFO-filen från systemet & avsluta programmet */
|
||||
if ( unlink(FIFONAM) == -1 )
|
||||
{
|
||||
perror("cleanUp - unlink");
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
45
kapitel17/my-msg-recv.c
Normal file
45
kapitel17/my-msg-recv.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX 100
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Struktur som krävs av msgsnd & msgrcv */
|
||||
struct msgbuf
|
||||
{
|
||||
long mtype;
|
||||
char mtext[MAX];
|
||||
};
|
||||
|
||||
int id;
|
||||
key_t key = 12345;
|
||||
struct msgbuf msg;
|
||||
msg.mtext[0] = '\0';
|
||||
|
||||
/* Kalla msgget för att få ett ID-nummer till kön.
|
||||
Observera att vi här utelämnar IPC_CREAT. */
|
||||
if ( (id = msgget(key, 0660)) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not open message queue\n");
|
||||
perror("msgget");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Ta emot meddelandet och spara det i msg */
|
||||
if ( msgrcv(id, &msg, MAX, 1, 0) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not receive messages\n");
|
||||
perror("msgrcv");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Skriv ut meddelandet */
|
||||
printf("%s\n", msg.mtext);
|
||||
|
||||
return 0;
|
||||
}
|
53
kapitel17/my-msg-send.c
Normal file
53
kapitel17/my-msg-send.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX 100
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Struktur som krävs av msgsnd & msgrcv */
|
||||
struct msgbuf
|
||||
{
|
||||
long mtype;
|
||||
char mtext[MAX];
|
||||
};
|
||||
|
||||
/* Variabler vi behöver */
|
||||
int id;
|
||||
key_t key = 12345;
|
||||
struct msgbuf msg;
|
||||
size_t msglen;
|
||||
msg.mtext[0] = '\0';
|
||||
|
||||
/* Kalla msgget för att få ett ID-nummer till kön.
|
||||
IPC_CREAT är flaggan för att skapa en kö. 0660
|
||||
är rättigheterna för kön */
|
||||
if ( (id = msgget(key, IPC_CREAT | 0660)) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not create message queue\n");
|
||||
perror("msgget");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Komponera ett testmeddelande. mtype är till för att
|
||||
identifiera just detta meddelandet i kön. mtext är
|
||||
det faktiska innehållet och msglen är längden på
|
||||
meddelandet */
|
||||
msg.mtype = 1;
|
||||
strcat(msg.mtext, "Hejsan svejsan");
|
||||
msglen = strlen(msg.mtext) + 1;
|
||||
|
||||
/* Skicka meddelandet */
|
||||
if ( msgsnd(id, &msg, msglen, IPC_NOWAIT) < 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not send message\n");
|
||||
perror("msgsend");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
27
kapitel17/pipes-ex1.c
Normal file
27
kapitel17/pipes-ex1.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#define MAX 7
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int pipefd[2];
|
||||
pid_t pid;
|
||||
char line[MAX];
|
||||
|
||||
pipe(pipefd);
|
||||
pid = fork();
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
close(pipefd[0]);
|
||||
write(pipefd[1], "Hejsan", MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
close(pipefd[1]);
|
||||
read(pipefd[0], line, MAX);
|
||||
printf("%s\n", line);
|
||||
}
|
||||
return 0;
|
||||
}
|
61
kapitel17/sig-client.c
Normal file
61
kapitel17/sig-client.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void printUsage(char *arg);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
int opt;
|
||||
pid_t process_id;
|
||||
char pidfile[] = "/tmp/daemon-sig-ex.pid";
|
||||
|
||||
/* Kontrollera ifall PID-filen finns */
|
||||
if ( (fp = fopen(pidfile, "r")) == 0 )
|
||||
{
|
||||
fprintf(stderr, "Ingen PID-fil, körs verkligen demonen?\n");
|
||||
return 1;
|
||||
}
|
||||
/* Läs in PID till process_id variabeln */
|
||||
fscanf(fp, "%d", &process_id);
|
||||
|
||||
/* Om inga argument angavs, skriv ut demonens PID */
|
||||
if (argc == 1)
|
||||
printf("Demonen körs med PID: %d\n", process_id);
|
||||
|
||||
/* Behandla argument till programmet */
|
||||
while ((opt = getopt(argc, argv, "utqh")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'u':
|
||||
kill(process_id, SIGUSR1);
|
||||
break;
|
||||
case 't':
|
||||
kill(process_id, SIGTERM);
|
||||
break;
|
||||
case 'q':
|
||||
kill(process_id, SIGQUIT);
|
||||
break;
|
||||
case 'h':
|
||||
printUsage(argv[0]);
|
||||
return 0;
|
||||
default:
|
||||
printUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printUsage(char *arg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-u] [-t] [-q] [-h]\n"
|
||||
"-u = send SIGUSR1 to daemon\n"
|
||||
"-t = send SIGTERM to daemon\n"
|
||||
"-q = send SIGQUIT to quit the daemon\n"
|
||||
"-h = display help\n", arg);
|
||||
}
|
48
kapitel17/unix-socket-client.c
Normal file
48
kapitel17/unix-socket-client.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#define MAXLEN 32
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const char sockname[] = "/tmp/tidssocket";
|
||||
int fd;
|
||||
struct sockaddr_un addr;
|
||||
char recvbuffer[MAXLEN];
|
||||
|
||||
/* skapa en socket fildeskriptor */
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if ( fd == -1 )
|
||||
{
|
||||
perror("Create socket failed");
|
||||
return 1;
|
||||
}
|
||||
/* sätt adressfamiljen och socket-filen */
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, sockname);
|
||||
|
||||
/* anslut till servern */
|
||||
if ( (connect(fd, (const struct sockaddr*) &addr,
|
||||
sizeof(struct sockaddr_un))) == -1 )
|
||||
{
|
||||
perror("Can't connect");
|
||||
fprintf(stderr, "The server is down?\n");
|
||||
return 1;
|
||||
}
|
||||
/* läs tiden från servern */
|
||||
if ( (read(fd, recvbuffer, MAXLEN)) == -1 )
|
||||
{
|
||||
perror("Can't read");
|
||||
return 1;
|
||||
}
|
||||
printf("Server time is: %s", recvbuffer);
|
||||
write(fd, "Thank you for the time", 23);
|
||||
return 0;
|
||||
}
|
87
kapitel17/unix-socket-server.c
Normal file
87
kapitel17/unix-socket-server.c
Normal file
@@ -0,0 +1,87 @@
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#define MAXLEN 32
|
||||
|
||||
void cleanUp(int signum);
|
||||
const char sockname[] = "/tmp/tidssocket";
|
||||
int connfd;
|
||||
int datafd;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
char buffer[MAXLEN];
|
||||
char recvbuffer[MAXLEN];
|
||||
time_t current_time;
|
||||
struct tm *local_time;
|
||||
|
||||
/* registrera signalhanterarna */
|
||||
signal(SIGTERM, cleanUp);
|
||||
signal(SIGABRT, cleanUp);
|
||||
signal(SIGQUIT, cleanUp);
|
||||
signal(SIGINT, cleanUp);
|
||||
|
||||
/* skapa en socket fildeskriptor */
|
||||
connfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if ( connfd == -1 )
|
||||
{
|
||||
perror("Create socket failed");
|
||||
return 1;
|
||||
}
|
||||
/* sätt adressfamiljen till UNIX-socket */
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, sockname);
|
||||
/* knyt ihop namnet och adressen och casta
|
||||
sockaddr_un till sockaddr) */
|
||||
if ( (bind(connfd, (const struct sockaddr*)&addr,
|
||||
sizeof(struct sockaddr_un))) == -1 )
|
||||
{
|
||||
perror("Binding socket failed");
|
||||
return 1;
|
||||
}
|
||||
/* lyssna efter anslutningar */
|
||||
if ( (listen(connfd, 20)) == -1 )
|
||||
{
|
||||
perror("Listen error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* acceptera anslutningen, skapa en ny data-fildeskriptor,
|
||||
och skicka tiden till klienten */
|
||||
while(1)
|
||||
{
|
||||
datafd = accept(connfd, NULL, NULL);
|
||||
if (datafd == -1 )
|
||||
{
|
||||
perror("Accept error");
|
||||
return 1;
|
||||
}
|
||||
printf("Client connected, sending time\n");
|
||||
current_time = time(NULL);
|
||||
local_time = localtime(¤t_time);
|
||||
strcpy(buffer, asctime(local_time));
|
||||
write(datafd, buffer, MAXLEN);
|
||||
read(datafd, recvbuffer, MAXLEN);
|
||||
printf("Client respons: %s\n", recvbuffer);
|
||||
close(datafd); /* stäng datafd efter varje anrop */
|
||||
}
|
||||
return 0; /* fall i fall */
|
||||
}
|
||||
|
||||
void cleanUp(int signum)
|
||||
{
|
||||
printf("Quitting and cleaning up\n");
|
||||
close(datafd);
|
||||
close(connfd);
|
||||
unlink(sockname);
|
||||
exit(0);
|
||||
}
|
Reference in New Issue
Block a user