Bokens exempelprogram
This commit is contained in:
commit
9fd3ac4a26
60
daemon-ex1.c
Normal file
60
daemon-ex1.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
pid_t process_id = 0;
|
||||||
|
pid_t sid = 0;
|
||||||
|
|
||||||
|
/* Skapa barn/child process */
|
||||||
|
process_id = fork();
|
||||||
|
|
||||||
|
/* Hantera eventuellt fel vid fork() */
|
||||||
|
if (process_id < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "fork failed!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Förälderprocessen/parent process.
|
||||||
|
Avsluta den eftersom allt arbete kommer att
|
||||||
|
utföras av demonen. Skriv också ut demonens PID */
|
||||||
|
else if (process_id > 0)
|
||||||
|
{
|
||||||
|
printf("Daemon process: %d \n", process_id);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sätt umask till 000 så att alla kan komma eventuella
|
||||||
|
filer skapade av demonen. Anpassas efter vad demonen
|
||||||
|
ska användas till */
|
||||||
|
umask(0);
|
||||||
|
/* Starta en ny session */
|
||||||
|
sid = setsid();
|
||||||
|
|
||||||
|
if(sid < 0)
|
||||||
|
{
|
||||||
|
/* Avsluta ifall det inte gick att skapa en ny
|
||||||
|
session */
|
||||||
|
fprintf(stderr, "Failure to set new session\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ä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);
|
||||||
|
|
||||||
|
/* Här börjar demonens arbete... */
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
sleep(5);
|
||||||
|
}
|
||||||
|
}
|
96
daemon-sig-ex1.c
Normal file
96
daemon-sig-ex1.c
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <syslog.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Förälderprocessen/parent process.
|
||||||
|
Avsluta den eftersom allt arbete kommer att
|
||||||
|
utföras av demonen. Skriv också ut demonens PID */
|
||||||
|
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 000 så att alla kan komma eventuella
|
||||||
|
filer skapade av demonen. Anpassas efter vad demonen
|
||||||
|
ska användas till */
|
||||||
|
umask(0);
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ä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);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
110
daemon-sig-ex2.c
Normal file
110
daemon-sig-ex2.c
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <syslog.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Förälderprocessen/parent process.
|
||||||
|
Avsluta den eftersom allt arbete kommer att
|
||||||
|
utföras av demonen. Skriv också ut demonens PID */
|
||||||
|
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 000 så att alla kan komma eventuella
|
||||||
|
filer skapade av demonen. Anpassas efter vad demonen
|
||||||
|
ska användas till */
|
||||||
|
umask(0);
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ä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);
|
||||||
|
|
||||||
|
/* 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, "Demonens avslutas");
|
||||||
|
/* Ta bort PID-filen efter oss */
|
||||||
|
if ( unlink(pidfile) == -1 )
|
||||||
|
syslog(LOG_DAEMON, "Kunde inte ta bort PID-filen");
|
||||||
|
exit(0);
|
||||||
|
}
|
74
fifo-ex1.c
Normal file
74
fifo-ex1.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#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);
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Kör i en oändlig loop */
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
fifofd = open(FIFONAM, O_WRONLY);
|
||||||
|
if (fifofd < 0)
|
||||||
|
{
|
||||||
|
perror("open");
|
||||||
|
return 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änd 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
my-msg-recv-rm.c
Normal file
45
my-msg-recv-rm.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);
|
||||||
|
msgctl(id, IPC_RMID, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
45
my-msg-recv.c
Normal file
45
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
my-msg-send.c
Normal file
53
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;
|
||||||
|
}
|
61
sig-client.c
Normal file
61
sig-client.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <getopt.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);
|
||||||
|
}
|
100
simple-ls-ver1.c
Normal file
100
simple-ls-ver1.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
void printUsage(char *arg);
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int typ;
|
||||||
|
char opt[5] = { 0 };
|
||||||
|
|
||||||
|
/* Skapa pekare och struct */
|
||||||
|
DIR *d;
|
||||||
|
struct dirent *dir;
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
/* Läs in aktuell katalog */
|
||||||
|
d = opendir(".");
|
||||||
|
/* Om 'd' INTE är sant (! = inte sant) */
|
||||||
|
if (!d)
|
||||||
|
{
|
||||||
|
printf("Kan inte läsa aktuell katalog\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Behandla arugment */
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
strncpy(opt, "-a", 2);
|
||||||
|
}
|
||||||
|
else if (argc == 2)
|
||||||
|
{
|
||||||
|
strncpy(opt, argv[1], 2);
|
||||||
|
|
||||||
|
/* Hjälptext */
|
||||||
|
if ( strcmp(opt, "-h") == 0 )
|
||||||
|
printUsage(argv[0]);
|
||||||
|
|
||||||
|
/* Visa endast filer */
|
||||||
|
else if ( strcmp(opt, "-f") == 0 )
|
||||||
|
{
|
||||||
|
typ = S_IFREG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Visa endast kataloger */
|
||||||
|
else if ( strcmp(opt, "-d") == 0 )
|
||||||
|
{
|
||||||
|
typ = S_IFDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Visa alla filer */
|
||||||
|
else if ( strcmp(opt, "-a") == 0 )
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Om vi angav ett felaktigt argument */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printUsage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Om vi angav fel antal argument */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printUsage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skriv ut innehållet i katalogen */
|
||||||
|
while ((dir = readdir(d)) != NULL)
|
||||||
|
{
|
||||||
|
if ( strcmp(opt, "-a") == 0 )
|
||||||
|
{
|
||||||
|
printf("%s\n", dir->d_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stat(dir->d_name, &s);
|
||||||
|
/* Se kapitlet om 'Bitvisa operationer' */
|
||||||
|
if ((s.st_mode & S_IFMT) == typ)
|
||||||
|
printf("%s\n", dir->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stäng "d" och returnera noll */
|
||||||
|
closedir(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printUsage(char *arg)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [-a] [-f] [-d]\n"
|
||||||
|
" -a to list all types (default)\n"
|
||||||
|
" -f to list only files\n"
|
||||||
|
" -d to list only directories\n", arg);
|
||||||
|
}
|
75
simple-ls-ver2.c
Normal file
75
simple-ls-ver2.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
void printUsage(char *arg);
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
int typ = -1;
|
||||||
|
char *path = ".";
|
||||||
|
|
||||||
|
/* Skapa pekare och struct */
|
||||||
|
DIR *d;
|
||||||
|
struct dirent *dir;
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
/* Behandla argument med getopt */
|
||||||
|
while ((opt = getopt(argc, argv, "hafdp:")) != -1)
|
||||||
|
{
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
typ = -1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
typ = S_IFREG;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
typ = S_IFDIR;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
path = optarg;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
printUsage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
printUsage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Byt katalog med chdir() för att stat() ska
|
||||||
|
se filerna i rätt katalog */
|
||||||
|
chdir(path);
|
||||||
|
|
||||||
|
d = opendir(path);
|
||||||
|
while ((dir = readdir(d)) != NULL)
|
||||||
|
{
|
||||||
|
if ( typ == -1 )
|
||||||
|
{
|
||||||
|
printf("%s\n", dir->d_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stat(dir->d_name, &s);
|
||||||
|
/* Se kapitlet om 'Bitvisa operationer' */
|
||||||
|
if ((s.st_mode & S_IFMT) == typ)
|
||||||
|
printf("%s\n", dir->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printUsage(char *arg)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [-a] [-f] [-d] [-p path]\n"
|
||||||
|
" -a to list all types (default)\n"
|
||||||
|
" -f to list only files\n"
|
||||||
|
" -d to list only directories\n"
|
||||||
|
" -p to specify a directory\n", arg);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user