P09 lab code added
This commit is contained in:
parent
94945069e3
commit
f4c374887c
|
@ -0,0 +1,178 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* File: Daemonizer.c
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: Einen Daemon-Prozess erzeugen
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
// Macro to write out all the PIDs...
|
||||||
|
|
||||||
|
#define OutPutPIDs() /*printf("\nPID %d, PPID %d, GRP-ID %d\n", \
|
||||||
|
getpid(), getppid(), getpgrp())*/
|
||||||
|
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: Locks file with file descriptor fd
|
||||||
|
// Returns: 0 on success, -1 of file is already locked
|
||||||
|
// Exits: on fatal errors
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
int lock(int fd) {
|
||||||
|
int retval, len;
|
||||||
|
struct flock lock; // data structure for file lock
|
||||||
|
char buffer[16];
|
||||||
|
|
||||||
|
// prepare lockfile
|
||||||
|
|
||||||
|
lock.l_type = F_WRLCK;
|
||||||
|
lock.l_start = 0;
|
||||||
|
lock.l_whence = SEEK_SET;
|
||||||
|
lock.l_len = 0;
|
||||||
|
|
||||||
|
retval = fcntl(fd, F_SETLK, &lock); // set file lock
|
||||||
|
if (retval < 0) {
|
||||||
|
if ((errno == EACCES) || (errno == EAGAIN)) {
|
||||||
|
return(-1); // Daemon already runs
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
perror("fatal error when locking file");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty the lockfile
|
||||||
|
|
||||||
|
retval = ftruncate(fd, 0);
|
||||||
|
if (retval < 0) {
|
||||||
|
perror("fatal error when emptying lockfile");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write process ID to lockfile
|
||||||
|
|
||||||
|
sprintf(buffer, "%d\n", getpid());
|
||||||
|
len = strlen(buffer);
|
||||||
|
retval = write(fd, buffer, len) < len;
|
||||||
|
if (retval < 0) {
|
||||||
|
perror("fatal error when writing pid to lockfile");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set lockfile to close on exec
|
||||||
|
|
||||||
|
retval = fcntl(fd, F_GETFD, 0);
|
||||||
|
if (retval < 0) {
|
||||||
|
perror("fatal error when reading lockfile flags");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
retval = retval | FD_CLOEXEC;
|
||||||
|
retval = fcntl(fd, F_SETFD, retval);
|
||||||
|
if (retval < 0) {
|
||||||
|
perror("fatal error when setting lockfile flags");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: Makes a deamon process and runs a daemon function
|
||||||
|
// Parameter: Daemon function
|
||||||
|
// data pointer to data to be passed to Daemonfunction
|
||||||
|
// LogFile, path of logfile, if NULL, no logfile is created
|
||||||
|
// LivDir, path, where daemon will live
|
||||||
|
// Returns: should not return
|
||||||
|
// Exits: if daemon is already runnung or on fatal errors
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
int Daemonizer(void Daemon(void *), void *data,
|
||||||
|
const char *LockFile, const char *LogFile, const char *LivDir) {
|
||||||
|
|
||||||
|
pid_t PID;
|
||||||
|
int fd, dummyfd, retval;
|
||||||
|
|
||||||
|
// create a prozess and terminate parents -> parent is init
|
||||||
|
|
||||||
|
OutPutPIDs();
|
||||||
|
|
||||||
|
PID = fork();
|
||||||
|
if (PID < 0) {
|
||||||
|
perror("could not fork()");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
else if (PID > 0) {
|
||||||
|
exit(0); // I have done my work an can exit
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// now I am a process detached from the parent
|
||||||
|
// an make the process -> a daemon process
|
||||||
|
|
||||||
|
signal(SIGINT, SIG_IGN); // ignore CTRL-C
|
||||||
|
signal(SIGQUIT, SIG_IGN); // ignore quit
|
||||||
|
signal(SIGHUP, SIG_IGN); // ignore hangup of terminal
|
||||||
|
|
||||||
|
OutPutPIDs();
|
||||||
|
|
||||||
|
setsid(); // make process session leader
|
||||||
|
// and processgroup leader
|
||||||
|
// no control terminal with pocess
|
||||||
|
OutPutPIDs();
|
||||||
|
|
||||||
|
chdir(LivDir); // change to secure directory
|
||||||
|
umask(0); // allow all access rights for files
|
||||||
|
|
||||||
|
// set up lockfile, if required
|
||||||
|
|
||||||
|
if (LockFile != NULL) {
|
||||||
|
fd = open(LockFile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
|
||||||
|
S_IRGRP | S_IROTH);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("fatal error when opening lockfile");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
retval = lock(fd);
|
||||||
|
if (retval < 0) {
|
||||||
|
printf("\n*** daemon is already running ***\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// last message from daemon
|
||||||
|
|
||||||
|
printf("\n*** daemon starts with process id: %d ***\n",getpid());
|
||||||
|
|
||||||
|
// close "communication" to outer world and set up logging, if required
|
||||||
|
|
||||||
|
close(1); // close stdout
|
||||||
|
close(2); // close stderr
|
||||||
|
if (LogFile != NULL) { // open log file on stdout
|
||||||
|
enum {UserWrite=0644};
|
||||||
|
dummyfd = open(LogFile, O_CREAT | O_APPEND | O_WRONLY,UserWrite);
|
||||||
|
if (dummyfd < 0) {
|
||||||
|
perror("could not open log file");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
dup(1); // connect stderr to logfile
|
||||||
|
}
|
||||||
|
close(0); // now close stdin
|
||||||
|
|
||||||
|
// now start the daemon funktion
|
||||||
|
Daemon(data);
|
||||||
|
|
||||||
|
// should not come here
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* File: Daemonizer.h
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: einen Daemon-Prozess erzeugen
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifndef DAEMONIZER_H
|
||||||
|
#define DAEMONIZER_H
|
||||||
|
|
||||||
|
int Daemonizer(void Daemon(void *), void *data,
|
||||||
|
const char *LockFile, const char *LogFile, const char *LivDir);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
|
@ -0,0 +1,188 @@
|
||||||
|
//*****************************************************************************
|
||||||
|
// ipCom.c IP Socket Functions
|
||||||
|
// Original Author: M. Thaler, M. Pellaton (Modul BSY)
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// system includes
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// local definitions
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#include "IPsockCom.h"
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: send data buffer to host "host" with port "port"
|
||||||
|
// Parameter: hostname or IP address in dot format
|
||||||
|
// port number
|
||||||
|
// buffer
|
||||||
|
// size of buffer
|
||||||
|
// Returns: number of characters read on success, -1 if connection failed
|
||||||
|
// buffer: time data
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
int getTimeFromServer(char *host, int port, char *buffer, int bufferLen) {
|
||||||
|
|
||||||
|
int sfd, sysRet, timeOut, retval;
|
||||||
|
char stringPort[8];
|
||||||
|
struct addrinfo hints, *aiList, *aiPtr = NULL;
|
||||||
|
|
||||||
|
if (strcmp(host, "") == 0) {
|
||||||
|
printf("Need hostname or IP address\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(stringPort, "%d", port);
|
||||||
|
|
||||||
|
memset(&hints, '\0', sizeof(hints));
|
||||||
|
//hints.ai_flags = AI_CANONNAME;
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
|
sysRet = getaddrinfo(host, stringPort, &hints, &aiList);
|
||||||
|
if (sysRet != 0) {
|
||||||
|
printf("error getting network address for %s (%s)\n",
|
||||||
|
host, gai_strerror(sysRet));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
aiPtr = aiList; // search through list
|
||||||
|
while (aiPtr != 0) {
|
||||||
|
sfd = socket(aiPtr->ai_family, aiPtr->ai_socktype, aiPtr->ai_protocol);
|
||||||
|
if (sfd >= 0) {
|
||||||
|
timeOut = 100;
|
||||||
|
sysRet = 1;
|
||||||
|
while ((timeOut != 0) && (sysRet != 0)) {
|
||||||
|
sysRet = connect(sfd, aiPtr->ai_addr, aiPtr->ai_addrlen);
|
||||||
|
usleep(1000);
|
||||||
|
timeOut--;
|
||||||
|
}
|
||||||
|
if (sysRet == 0)
|
||||||
|
break; // connect successful
|
||||||
|
else
|
||||||
|
close(sfd);
|
||||||
|
}
|
||||||
|
aiPtr = aiPtr->ai_next;
|
||||||
|
}
|
||||||
|
freeaddrinfo(aiList);
|
||||||
|
if (aiPtr == NULL) {
|
||||||
|
printf("could not connect to %s\n", host);
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
if (retval == 0) {
|
||||||
|
if (write(sfd, buffer, bufferLen) < 0) {
|
||||||
|
printf("error sending request to timer serveer\n");
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retval = read(sfd, buffer, COM_BUF_SIZE);
|
||||||
|
}
|
||||||
|
close(sfd);
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: starts "time" socket server
|
||||||
|
// Parameter: port number to listen to
|
||||||
|
// Returns: socket file descriptor if ok, -1 if error
|
||||||
|
// Exits:
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
int StartTimeServer(int portNumber) {
|
||||||
|
|
||||||
|
int sfd, sysRet, j;
|
||||||
|
char stringPort[8];
|
||||||
|
struct addrinfo hints, *aiList, *aiPtr = NULL;
|
||||||
|
|
||||||
|
sprintf(stringPort, "%d", portNumber); // portnumber to string
|
||||||
|
memset(&hints, '\0', sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = 0;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
|
sysRet = getaddrinfo(NULL, stringPort, &hints, &aiList);
|
||||||
|
if (sysRet != 0) {
|
||||||
|
printf("error getting network address (%s)\n", gai_strerror(sysRet));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
aiPtr = aiList; // search through list
|
||||||
|
while (aiPtr != 0) {
|
||||||
|
sfd = socket(aiPtr->ai_family, aiPtr->ai_socktype, aiPtr->ai_protocol);
|
||||||
|
if (sfd >= 0) {
|
||||||
|
j = 1;
|
||||||
|
sysRet = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &j, sizeof(j));
|
||||||
|
if (sysRet < 0)
|
||||||
|
perror("cannot set socket options");
|
||||||
|
|
||||||
|
if (bind(sfd, aiPtr->ai_addr, aiPtr->ai_addrlen) < 0) {
|
||||||
|
perror("bind failed ");
|
||||||
|
close(sfd);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (listen(sfd, 5) < 0) {
|
||||||
|
close(sfd);
|
||||||
|
perror("listen failed ");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
aiPtr = aiPtr->ai_next;
|
||||||
|
}
|
||||||
|
freeaddrinfo(aiList);
|
||||||
|
if (aiPtr == NULL) {
|
||||||
|
printf("could not set up a socket server\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
return(sfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: Reads data from client
|
||||||
|
// Parameter: socket file descriptor
|
||||||
|
// buffer to place data
|
||||||
|
// Returns: current socket descriptor on success, < 0 on failure
|
||||||
|
// Exits: none
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
int WaitForClient(int sfd, char *buffer) {
|
||||||
|
|
||||||
|
int cfd, retval, addrlen;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
|
cfd = accept(sfd,(struct sockaddr *)&addr,(socklen_t *)&addrlen);
|
||||||
|
if (cfd >= 0) {
|
||||||
|
retval = read(cfd, buffer, COM_BUF_SIZE);
|
||||||
|
retval = cfd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retval = cfd;
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
|
@ -0,0 +1,20 @@
|
||||||
|
//*****************************************************************************
|
||||||
|
// ipCom.c IP Socket Functions
|
||||||
|
// Original Autor: M. Thaler, M. Pellaton (Modul BSY)
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#ifndef IP_COM_SOCKETS
|
||||||
|
#define IP_COM_SOCKETS
|
||||||
|
|
||||||
|
#define COM_BUF_SIZE 512
|
||||||
|
|
||||||
|
#define PIDperror()\
|
||||||
|
fprintf(stderr,"fatal error, daemon with PID %d: ",getpid());
|
||||||
|
|
||||||
|
int getTimeFromServer(char *host, int port, char *buffer, int bufferLen);
|
||||||
|
int StartTimeServer(int PortNumber);
|
||||||
|
int WaitForClient(int sfd, char *buffer);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* File: MrTimeDaemon.c
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: einen Daemon-Prozess erzeugen
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "Daemonizer.h"
|
||||||
|
#include "TimeDaemon.h"
|
||||||
|
|
||||||
|
#define STRING_LENGTH 128
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
const char *lockfilePath = "/tmp/timeDaemon.lock";
|
||||||
|
//const char *lockfilePath = NULL;
|
||||||
|
const char *logfilePath = "/tmp/timeDaemon.log";
|
||||||
|
const char *livingPath = "/tmp";
|
||||||
|
const char *myName = "I am Mr. Time Daemon on \n";
|
||||||
|
|
||||||
|
|
||||||
|
if ((pid = fork()) == 0)
|
||||||
|
Daemonizer(TimeDaemon, (void *)myName,
|
||||||
|
lockfilePath, logfilePath, livingPath);
|
||||||
|
else {
|
||||||
|
assert(pid > 0);
|
||||||
|
wait(&status); // wait for Daemonizer to exit
|
||||||
|
// after having forked the "Daemon"
|
||||||
|
if (WEXITSTATUS(status) != 0)
|
||||||
|
printf("*** Daemonizer failed ***\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* File: PlapperMaul.c
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: plappern
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
printf("Hallo, ich bins.... Pidi %d\n", getpid());
|
||||||
|
usleep(500000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
|
@ -0,0 +1,75 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* File: TimeDaemon.c
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: the daemon code
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// system includes
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// local includes
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#include "TimeDaemon.h"
|
||||||
|
#include "TimeDaemonDefs.h"
|
||||||
|
#include "IPsockCom.h"
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: TimeDeamon
|
||||||
|
// Parameter: data: expects here pointer to string
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
void TimeDaemon(void *data) {
|
||||||
|
|
||||||
|
TimeData tData;
|
||||||
|
char buffer[COM_BUF_SIZE];
|
||||||
|
struct tm MyTime;
|
||||||
|
time_t ActualTime;
|
||||||
|
int sfd, cfd;
|
||||||
|
|
||||||
|
|
||||||
|
printf("%s\n", (char *)data);
|
||||||
|
|
||||||
|
// start server
|
||||||
|
sfd = StartTimeServer(TIME_PORT);
|
||||||
|
if (sfd < 0) {
|
||||||
|
perror("could not start socket server");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
cfd = WaitForClient(sfd, buffer);
|
||||||
|
if ((strcmp(buffer, REQUEST_STRING) == 0) && (cfd >= 0)) {
|
||||||
|
|
||||||
|
time(&ActualTime);
|
||||||
|
MyTime = *localtime(&ActualTime);
|
||||||
|
|
||||||
|
tData.hours = MyTime.tm_hour;
|
||||||
|
tData.minutes = MyTime.tm_min;
|
||||||
|
tData.seconds = MyTime.tm_sec;
|
||||||
|
tData.day = MyTime.tm_mday;
|
||||||
|
tData.month = MyTime.tm_mon + 1;
|
||||||
|
tData.year = MyTime.tm_year + 1900;
|
||||||
|
gethostname(tData.servername, HOST_NAM_LEN);
|
||||||
|
write(cfd, (char *)(&tData), sizeof(tData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if we should somehow come here (how ?)
|
||||||
|
close(sfd);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
|
@ -0,0 +1,14 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* File: TimeDaemon.h
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: function prototype of time daemon
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TIME_DAEMON
|
||||||
|
#define TIME_DAEMON
|
||||||
|
|
||||||
|
void TimeDaemon(void *);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//*****************************************************************************
|
|
@ -0,0 +1,30 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* File: TimeDaemonDefs.h
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: Data Definitions for TimeDaemon
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TIME_DAEMON_DEFS
|
||||||
|
#define TIME_DAEMON_DEFS
|
||||||
|
|
||||||
|
#define HOST_NAM_LEN 32
|
||||||
|
|
||||||
|
#define TIME_PORT 65534
|
||||||
|
|
||||||
|
#define REQUEST_STRING "requestTimeFromServer"
|
||||||
|
|
||||||
|
// data structure receiving from time daemon
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int hours;
|
||||||
|
int minutes;
|
||||||
|
int seconds;
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
char servername[HOST_NAM_LEN];
|
||||||
|
} TimeData, *TimeDataPtr;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//*****************************************************************************
|
|
@ -0,0 +1,66 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* File: WhatsTheTimeMr.c
|
||||||
|
* Original Autor: M. Thaler (Modul BSY)
|
||||||
|
* Aufgabe: Ask MrTimeDaemon for the time
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// system includes
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <arpa/inet.h> // required by inet_aton
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// local includes
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#include "TimeDaemon.h"
|
||||||
|
#include "TimeDaemonDefs.h"
|
||||||
|
#include "IPsockCom.h"
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: main()
|
||||||
|
// Parameter: hostname or IP address in dot format
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
char buffer[COM_BUF_SIZE];
|
||||||
|
char hostname[64];
|
||||||
|
TimeDataPtr tDataPtr;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("*** no hostname or IP-address -> using localhost ***\n");
|
||||||
|
strcpy(hostname, "localhost");
|
||||||
|
} else {
|
||||||
|
strcpy(hostname, argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(buffer,REQUEST_STRING);
|
||||||
|
j = getTimeFromServer(hostname, TIME_PORT, buffer, sizeof(buffer));
|
||||||
|
if (j < 0)
|
||||||
|
printf("no response from %s\n", argv[1]);
|
||||||
|
else {
|
||||||
|
tDataPtr = (TimeDataPtr)(buffer);
|
||||||
|
printf("\nIt's ");
|
||||||
|
printf("%02d:%02d:%02d",
|
||||||
|
tDataPtr->hours, tDataPtr->minutes,tDataPtr->seconds);
|
||||||
|
printf(" the %d.%d.%d on \"%s\"\n\n",
|
||||||
|
tDataPtr->day, tDataPtr->month,
|
||||||
|
tDataPtr->year, tDataPtr->servername);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall -g -std=gnu99
|
||||||
|
EXENAMES= MrTimeDaemon.e
|
||||||
|
EXENAMEC= WhatsTheTimeMr.e
|
||||||
|
EXENAMEP= PlapperMaul.e
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
compile: $(EXENAMES) $(EXENAMEC) $(EXENAMEP)
|
||||||
|
|
||||||
|
$(EXENAMES): MrTimeDaemon.o IPsockCom.o Daemonizer.o TimeDaemon.o
|
||||||
|
$(CMP) $(CMPFLAGS) MrTimeDaemon.o IPsockCom.o Daemonizer.o TimeDaemon.o $(LIBNAME) -o $(EXENAMES)
|
||||||
|
|
||||||
|
$(EXENAMEC): WhatsTheTimeMr.o IPsockCom.o
|
||||||
|
$(CMP) $(CMPFLAGS) WhatsTheTimeMr.o IPsockCom.o $(LIBNAME) -o $(EXENAMEC)
|
||||||
|
|
||||||
|
$(EXENAMEP): PlapperMaul.o
|
||||||
|
$(CMP) $(CMPFLAGS) PlapperMaul.o $(LIBNAME) -o $(EXENAMEP)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXENAMEC) $(EXENAMES) $(EXENAMEP)
|
||||||
|
rm -f *.o
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
|
@ -0,0 +1,53 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA1.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 5;
|
||||||
|
|
||||||
|
printf("\n\ni vor fork: %d\n\n", i);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
i++;
|
||||||
|
printf("\n... ich bin das Kind %d mit i=%d, ", getpid(),i);
|
||||||
|
printf("meine Eltern sind %d \n", getppid());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
i--;
|
||||||
|
printf("\n... wir sind die Eltern %d mit i=%d ", getpid(), i);
|
||||||
|
printf("und Kind %d,\n unsere Eltern sind %d\n", pid, getppid());
|
||||||
|
wait(&status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n. . . . . und wer bin ich ?\n\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAM1= ProcA1.e
|
||||||
|
FNAM1= ProcA1
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
$(EXENAM1): $(FNAM1).o
|
||||||
|
$(CMP) $(FNAM1).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAM1)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
|
@ -0,0 +1,38 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ChildProcA3.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: arg[0]: Programmname, arg[1]: i
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argv[1] == NULL) {
|
||||||
|
printf("argument missing\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i = atoi(argv[1]); // convert string argv[1] to integer i
|
||||||
|
// argv[1] is a number passed to child
|
||||||
|
|
||||||
|
printf("\n... ich bin das Kind %d mit i=%d, ", getpid(),i);
|
||||||
|
printf("meine Eltern sind %d \n", getppid());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,54 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA3.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
int i, retval;
|
||||||
|
char str[8];
|
||||||
|
|
||||||
|
i = 5;
|
||||||
|
|
||||||
|
printf("\n\ni vor fork: %d\n\n", i);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
i++;
|
||||||
|
sprintf(str, "%d",i); // convert integer i to string str
|
||||||
|
retval = execl("./ChildProcA2.e", "ChildProcA2.e", str, NULL);
|
||||||
|
if (retval < 0) perror("\nexecl not successful");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
i--;
|
||||||
|
printf("\n... wir sind die Eltern %d mit i=%d ", getpid(), i);
|
||||||
|
printf("und Kind %d,\n unsere Eltern sind %d\n", pid, getppid());
|
||||||
|
wait(&status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n. . . . . und wer bin ich ?\n\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,34 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAME= ProcA2.e
|
||||||
|
FNAME= ProcA2
|
||||||
|
EXENAMC= ChildProcA2.e
|
||||||
|
FNAMC= ChildProcA2
|
||||||
|
LIBNAME=
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
compile: $(EXENAME) $(EXENAMC)
|
||||||
|
|
||||||
|
$(EXENAME): $(FNAME).o
|
||||||
|
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
$(EXENAMC): $(FNAMC).o
|
||||||
|
$(CMP) $(FNAMC).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAME) $(EXENAMC)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
|
@ -0,0 +1,31 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA4.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
fork();
|
||||||
|
fork();
|
||||||
|
fork();
|
||||||
|
fork();
|
||||||
|
printf("PID: %d\t PPID: %d\n", getpid(), getppid());
|
||||||
|
sleep(10); // keep processes in system to display their "stammbaum"
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,27 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAMES= ProcA3.e
|
||||||
|
FNAME= ProcA3
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
$(EXENAMES): $(FNAME).o
|
||||||
|
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAMES)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA5.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "workerUtils.h"
|
||||||
|
#include "selectCPU.h"
|
||||||
|
|
||||||
|
#define ITERATIONS 20
|
||||||
|
#define WORK_HARD 2000000
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
selectCPU(0); // select CPU 0
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
for (i = 0; i < ITERATIONS; i++) {
|
||||||
|
justWork(WORK_HARD);
|
||||||
|
printf("%d \t\tChild\n", i);
|
||||||
|
fflush(stdout); // force output
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
for (i = 0; i < ITERATIONS; i++) {;
|
||||||
|
justWork(WORK_HARD);
|
||||||
|
printf("%d \tMother\n", i);
|
||||||
|
fflush(stdout); // force output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("I go it ...\n");
|
||||||
|
|
||||||
|
if (pid > 0) // wait for child to terminate
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
setCPU() does not work on OSX
|
|
@ -0,0 +1,27 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAM1= ProcA4.e
|
||||||
|
FNAM1= ProcA4.o workerUtils.o selectCPU.o
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
$(EXENAM1): $(FNAM1)
|
||||||
|
$(CMP) $(FNAM1) $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAM1)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: setCPU.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
#include <sched.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
|
||||||
|
void selectCPU(unsigned int n) {
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
if (n >= sysconf(_SC_NPROCESSORS_ONLN)) {
|
||||||
|
printf("CPU %d not availble\n", n);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
sched_getaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||||
|
CPU_ZERO(&cpuset);
|
||||||
|
CPU_SET(n, &cpuset);
|
||||||
|
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
void selectCPU(unsigned int n) {
|
||||||
|
printf("Cannot set single CPU on OSX\n ... continue anyway");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
//*******************************************************************
|
||||||
|
// File: selectCPU.h
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//*******************************************************************
|
||||||
|
|
||||||
|
#ifndef SET_CPUS_HEADER_FILE
|
||||||
|
#define SET_CPUS_HEADER_FILE
|
||||||
|
|
||||||
|
//*******************************************************************
|
||||||
|
|
||||||
|
void selectCPU(unsigned int n);
|
||||||
|
|
||||||
|
//*******************************************************************
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,90 @@
|
||||||
|
//*******************************************************************
|
||||||
|
// File: workerUtils.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
// Purpose: helper applications to consume cpu time
|
||||||
|
//*******************************************************************
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "workerUtils.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#define MAX_CPUS 16
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
pid_t worker[MAX_CPUS];
|
||||||
|
int nCPUS;
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void launchWorkLoad() {
|
||||||
|
int i;
|
||||||
|
nCPUS = sysconf(_SC_NPROCESSORS_ONLN); // get number of available CPUs
|
||||||
|
nCPUS = (nCPUS > MAX_CPUS) ? MAX_CPUS : nCPUS;
|
||||||
|
for (i = 0; i < nCPUS; i++) // start workers -> random load
|
||||||
|
worker[i] = startWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopWorkLoad() {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nCPUS; i++) // stop worker
|
||||||
|
stopWorker(worker[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setRandom(void) {
|
||||||
|
srandom((unsigned int)time(NULL)); // new random sequence
|
||||||
|
}
|
||||||
|
|
||||||
|
void justWork(unsigned int load) {
|
||||||
|
unsigned int j;
|
||||||
|
for (j = 0; j < load; j++) {}; // just work
|
||||||
|
}
|
||||||
|
|
||||||
|
void workHard(unsigned int low, unsigned int high) {
|
||||||
|
double rv;
|
||||||
|
unsigned int us, j;
|
||||||
|
high = high - low;
|
||||||
|
rv = ((double)random())/RAND_MAX; // make random value (0..1)
|
||||||
|
us = low + (unsigned int)(rv * high); // between lower & higher limit
|
||||||
|
for (j = 0; j < us; j++) {}; // just work
|
||||||
|
setRandom(); // reseed random generator
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomSleep(unsigned int low, unsigned int high) {
|
||||||
|
double rv;
|
||||||
|
unsigned int us;
|
||||||
|
high = high - low;
|
||||||
|
rv = ((double)random())/RAND_MAX; // make random value (0..1)
|
||||||
|
us = low + (unsigned int)(rv * high); // between lower & higher limit
|
||||||
|
usleep(us*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pid_t startWorker(void) { // make a hard working process
|
||||||
|
struct timeval tv; // limit run time to 60 secs
|
||||||
|
time_t st;
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid == 0) { // child: pid = 0 -> ifinite loop
|
||||||
|
gettimeofday(&tv, NULL); // take start time
|
||||||
|
st = tv.tv_sec;
|
||||||
|
while ((tv.tv_sec-st) < 60) {
|
||||||
|
workHard(50, 800); // work hard (random interval
|
||||||
|
gettimeofday(&tv, NULL); // between 50us and 800us)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (pid < 0) { // exit fork failed
|
||||||
|
printf("forking worker failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
return pid; // return pid if parent
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopWorker(pid_t worker) {
|
||||||
|
kill(worker, SIGKILL); // terminate worker process
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
//*******************************************************************
|
||||||
|
// File: workerUtils.h
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
// Purpose: helper applications to consume cpu time
|
||||||
|
//*******************************************************************
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#define MAX_CPUS 16
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void launchWorkLoad();
|
||||||
|
|
||||||
|
void stopWorkLoad();
|
||||||
|
|
||||||
|
void setRandom(void);
|
||||||
|
|
||||||
|
void justWork(unsigned int load);
|
||||||
|
|
||||||
|
void workHard(unsigned int low, unsigned int high);
|
||||||
|
|
||||||
|
void randomSleep(unsigned int low, unsigned int high);
|
||||||
|
|
||||||
|
pid_t startWorker(void);
|
||||||
|
|
||||||
|
void stopWorker(pid_t worker);
|
|
@ -0,0 +1,51 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA6.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pid_t pid, id;
|
||||||
|
char buf[64];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
printf("\n... ich bin das Kind %d\n", getpid());
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
usleep(500000); // slow down a bit
|
||||||
|
printf("Mein Elternprozess ist %d\n", id = getppid());
|
||||||
|
}
|
||||||
|
printf("... so das wars\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sleep(2); // terminate
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n\n*** and here my new parent ****\n\n");
|
||||||
|
sprintf(buf, "ps -p %d", id);
|
||||||
|
system(buf);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,3 @@
|
||||||
|
Reparenting -> new parent instead init (1):
|
||||||
|
|
||||||
|
command prctl(PR_SET_CHILD_SUBREAPER, 1)
|
|
@ -0,0 +1,26 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAMES= ProcA5.e
|
||||||
|
FNAME= ProcA5
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
$(EXENAMES): $(FNAME).o
|
||||||
|
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAMES)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
|
@ -0,0 +1,48 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA7.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j = 0; j < 3; j++) { // generate 3 processes
|
||||||
|
pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
sleep(j+2); // process j sleeps for j+2 sec
|
||||||
|
exit(0); // then exits
|
||||||
|
break;
|
||||||
|
default: // parent
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleep(8); // parent process sleeps for 6 sec
|
||||||
|
wait(NULL); // consult manual for "wait"
|
||||||
|
sleep(2);
|
||||||
|
wait(NULL);
|
||||||
|
sleep(2);
|
||||||
|
wait(NULL);
|
||||||
|
sleep(2);
|
||||||
|
exit(0);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAMES= aaaa.e
|
||||||
|
FNAME= ProcA6
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
$(EXENAMES): $(FNAME).o
|
||||||
|
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAMES)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# M. Thaler, InIT/ZHAW 11/2014
|
||||||
|
# Version v.fs20
|
||||||
|
|
||||||
|
if test "$1" = ""
|
||||||
|
then
|
||||||
|
cmd="-a"
|
||||||
|
else
|
||||||
|
cmd="-C $1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
forever="1"
|
||||||
|
while test "$forever" = "1"
|
||||||
|
do
|
||||||
|
clear
|
||||||
|
ps $cmd
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ChildProcA8.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: arg[0]: Programmname, arg[1]: i
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
int i = 0, *a = NULL;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
i = atoi(argv[1]); // convert string argv[1] to integer i
|
||||||
|
// argv[1] is a number passed to child
|
||||||
|
|
||||||
|
printf("\n*** I am the child having job nr. %d ***\n\n", i);
|
||||||
|
|
||||||
|
switch(i) {
|
||||||
|
case 0: exit(0); // exit normally
|
||||||
|
break;
|
||||||
|
case 1: *a = i; // force segmentation error
|
||||||
|
break;
|
||||||
|
case 2: kill(getpid(), 30); // I send signal 30 to myself
|
||||||
|
break;
|
||||||
|
case 3: sleep(5); // sleep and wait for signal
|
||||||
|
break;
|
||||||
|
case 4: sleep(5); // just sleep
|
||||||
|
exit(222); // then exit
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,65 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA8.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
pid_t pid;
|
||||||
|
int status, retval, whatToDo = 0;
|
||||||
|
char str[8];
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
whatToDo = atoi(argv[1]); // get job number for child
|
||||||
|
|
||||||
|
pid = fork(); // fork child
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
sprintf(str, "%d",whatToDo);
|
||||||
|
retval = execl("./ChildProcA7.e", "ChildProcA7.e", str, NULL);
|
||||||
|
if (retval < 0) perror("\nexecl not successful");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (whatToDo <= 3) {
|
||||||
|
if (whatToDo == 3) {
|
||||||
|
sleep(1);
|
||||||
|
kill(pid, SIGABRT); // send signal SIGABTR to child
|
||||||
|
}
|
||||||
|
wait(&status);
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
printf("Child exits with status %d\n", WEXITSTATUS(status));
|
||||||
|
if (WIFSIGNALED(status)) {
|
||||||
|
printf("Child exits on signal %d\n", WTERMSIG(status));
|
||||||
|
printf("Child exits with core dump %d\n", WCOREDUMP(status));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
usleep(500*1000);
|
||||||
|
while (!waitpid(pid, &status, WNOHANG)) {
|
||||||
|
printf(". . . child is playing\n");
|
||||||
|
usleep(500*1000);
|
||||||
|
}
|
||||||
|
printf("Child has exited with 'exit(%d)'\n", WEXITSTATUS(status));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
Enable core dumps -> ulimit -c unlimited
|
||||||
|
Disable core dumps -> ulimit -c 0
|
||||||
|
|
||||||
|
Das core File lesen mit gdb:
|
||||||
|
|
||||||
|
gdb -c core ChildProgA8.e
|
||||||
|
|
||||||
|
|
||||||
|
!!!! Wichtig !!!!
|
||||||
|
|
||||||
|
Wenn sie ein Linux benutzen, das standardmaessig ABRT (Automatic Bug
|
||||||
|
Reporting Tool) verwendet (z.B. Fedora, Centos, etc.), muss
|
||||||
|
/proc/sys/kernel/core_pattern auf "core" gesetzt werden, damit ein
|
||||||
|
core File erzeugt wird
|
||||||
|
|
||||||
|
echo core > /proc/sys/kernel/core_pattern
|
||||||
|
|
||||||
|
Wenn ihr System SE-Linux verwendet (z.B. Fedora) , laesst sich core_pattern
|
||||||
|
nicht auf einfache Art setzen, verzichten sie in diesem Fall auf die
|
||||||
|
Erzeugung des "core" Files.
|
|
@ -0,0 +1,34 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc
|
||||||
|
CMPFLAGS= -Wall -g
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAME= ProcA7.e
|
||||||
|
FNAME= ProcA7
|
||||||
|
EXENAMC= ChildProcA7.e
|
||||||
|
FNAMC= ChildProcA7
|
||||||
|
LIBNAME=
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
compile: $(EXENAME) $(EXENAMC)
|
||||||
|
|
||||||
|
$(EXENAME): $(FNAME).o
|
||||||
|
$(CMP) $(FNAME).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
$(EXENAMC): $(FNAMC).o
|
||||||
|
$(CMP) $(FNAMC).o $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core *.o $(EXENAME) $(EXENAMC)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
|
@ -0,0 +1,45 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA9_1.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("\nHallo, I am on the way to fork now, ......lo");
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
printf("ok: I am the child\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("ok: I am the parent\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\nclear ?\n\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA9_2.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define WAIT_TIME (200*1000) // 0.2 s with usleep
|
||||||
|
|
||||||
|
// globaler array
|
||||||
|
|
||||||
|
#define ARRAY_SIZE 8
|
||||||
|
char GArray[ARRAY_SIZE][ARRAY_SIZE];
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
int i,j;
|
||||||
|
|
||||||
|
// flip coin to select "child first" or "parent first"
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
srandom(tv.tv_usec); // evaluate seed
|
||||||
|
int head = (int)(random()) >> 7; // flip coin
|
||||||
|
head &= 0x1;
|
||||||
|
|
||||||
|
// fill global array with '-' and print array value
|
||||||
|
for (i = 0; i < ARRAY_SIZE; i++) {
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++) {
|
||||||
|
GArray[i][j] = '-';
|
||||||
|
printf("%c ", GArray[i][j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0: // --- child fills upper half of array with 'c'
|
||||||
|
if (head) usleep(WAIT_TIME);
|
||||||
|
for (i = ARRAY_SIZE / 2; i < ARRAY_SIZE; i++)
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
GArray[i][j] = 'c';
|
||||||
|
break;
|
||||||
|
default: // --- parent fills lower half of array with 'p'
|
||||||
|
if (! head) usleep(WAIT_TIME);
|
||||||
|
for (i = 0; i < ARRAY_SIZE / 2; i++)
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
GArray[i][j] = 'p';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
printf("\nKinderarray\n\n");
|
||||||
|
else
|
||||||
|
printf("\nElternarray\n\n");
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE; i++) {
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
printf("%c ", GArray[i][j]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (pid > 0) wait(NULL);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
|
@ -0,0 +1,74 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA9_3.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "workerUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ANZAHL 15
|
||||||
|
#define WORK_HARD 1000000
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
FILE *fdes;
|
||||||
|
pid_t pid;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
launchWorkLoad(); // start CPU load to force context switches
|
||||||
|
fdes = fopen("AnyOutPut.txt", "w");
|
||||||
|
if (fdes == NULL) perror("Cannot open file");
|
||||||
|
|
||||||
|
usleep(500000);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
perror("Could not fork");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
for (i = 1; i <= ANZAHL; i++) {
|
||||||
|
fprintf(fdes, "Fritzli\t%d\n", i);
|
||||||
|
fflush(fdes); // make sure date is written to file
|
||||||
|
justWork(WORK_HARD);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
for (i = 1; i <= ANZAHL; i++) {
|
||||||
|
fprintf(fdes, "Mami\t%d\n", i);
|
||||||
|
fflush(fdes); // make sure date is written to file
|
||||||
|
justWork(WORK_HARD);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
stopWorkLoad();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("We are done\n");
|
||||||
|
if (pid > 0) {
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
printf("See file AnyOutPut.txt\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc -std=gnu99
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAME1= ProcA8_1.e
|
||||||
|
FNAM1= ProcA8_1.o
|
||||||
|
EXENAME2= ProcA8_2.e
|
||||||
|
FNAM2= ProcA8_2.o
|
||||||
|
EXENAME3= ProcA8_3.e
|
||||||
|
FNAM3= ProcA8_3.o workerUtils.o
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
compile: $(EXENAME1) $(EXENAME2) $(EXENAME3)
|
||||||
|
|
||||||
|
$(EXENAME1): $(FNAM1)
|
||||||
|
$(CMP) $(CMPFLAGS) $(FNAM1) $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
$(EXENAME2): $(FNAM2)
|
||||||
|
$(CMP) $(CMPFLAGS) $(FNAM2) $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
$(EXENAME3): $(FNAM3)
|
||||||
|
$(CMP) $(CMPFLAGS) $(FNAM3) $(LIBNAME) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAME1) $(EXENAME2) $(EXENAME3)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
|
@ -0,0 +1,90 @@
|
||||||
|
//*******************************************************************
|
||||||
|
// File workerUtils.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
// Purpose: helper applications to consume cpu time
|
||||||
|
//*******************************************************************
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "workerUtils.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#define MAX_CPUS 16
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
pid_t worker[MAX_CPUS];
|
||||||
|
int nCPUS;
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void launchWorkLoad() {
|
||||||
|
int i;
|
||||||
|
nCPUS = sysconf(_SC_NPROCESSORS_ONLN); // get number of available CPUs
|
||||||
|
nCPUS = (nCPUS > MAX_CPUS) ? MAX_CPUS : nCPUS;
|
||||||
|
for (i = 0; i < nCPUS; i++) // start workers -> random load
|
||||||
|
worker[i] = startWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopWorkLoad() {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nCPUS; i++) // stop worker
|
||||||
|
stopWorker(worker[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setRandom(void) {
|
||||||
|
srandom((unsigned int)time(NULL)); // new random sequence
|
||||||
|
}
|
||||||
|
|
||||||
|
void justWork(unsigned int load) {
|
||||||
|
unsigned int j;
|
||||||
|
for (j = 0; j < load; j++) {}; // just work
|
||||||
|
}
|
||||||
|
|
||||||
|
void workHard(unsigned int low, unsigned int high) {
|
||||||
|
double rv;
|
||||||
|
unsigned int us, j;
|
||||||
|
high = high - low;
|
||||||
|
rv = ((double)random())/RAND_MAX; // make random value (0..1)
|
||||||
|
us = low + (unsigned int)(rv * high); // between lower & higher limit
|
||||||
|
for (j = 0; j < us; j++) {}; // just work
|
||||||
|
setRandom(); // reseed random generator
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomSleep(unsigned int low, unsigned int high) {
|
||||||
|
double rv;
|
||||||
|
unsigned int us;
|
||||||
|
high = high - low;
|
||||||
|
rv = ((double)random())/RAND_MAX; // make random value (0..1)
|
||||||
|
us = low + (unsigned int)(rv * high); // between lower & higher limit
|
||||||
|
usleep(us*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pid_t startWorker(void) { // make a hard working process
|
||||||
|
struct timeval tv; // limit run time to 60 secs
|
||||||
|
time_t st;
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid == 0) { // child: pid = 0 -> ifinite loop
|
||||||
|
gettimeofday(&tv, NULL); // take start time
|
||||||
|
st = tv.tv_sec;
|
||||||
|
while ((tv.tv_sec-st) < 60) {
|
||||||
|
workHard(50, 800); // work hard (random interval
|
||||||
|
gettimeofday(&tv, NULL); // between 50us and 800us)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (pid < 0) { // exit fork failed
|
||||||
|
printf("forking worker failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
return pid; // return pid if parent
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopWorker(pid_t worker) {
|
||||||
|
kill(worker, SIGKILL); // terminate worker process
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
//*******************************************************************
|
||||||
|
// File: workerUtils.h
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//*******************************************************************
|
||||||
|
|
||||||
|
#ifndef WORKER_UTILS
|
||||||
|
#define WORKER_UTILS
|
||||||
|
|
||||||
|
void launchWorkLoad();
|
||||||
|
|
||||||
|
void stopWorkLoad();
|
||||||
|
|
||||||
|
void setRandom(void);
|
||||||
|
|
||||||
|
void justWork(unsigned int load);
|
||||||
|
|
||||||
|
void workHard(unsigned int low, unsigned int high);
|
||||||
|
|
||||||
|
void randomSleep(unsigned int low, unsigned int high);
|
||||||
|
|
||||||
|
pid_t startWorker(void);
|
||||||
|
|
||||||
|
void stopWorker(pid_t worker);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,112 @@
|
||||||
|
//***************************************************************************
|
||||||
|
// File: ProcA9.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// system includes
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "selectCPU.h"
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// global data
|
||||||
|
#define ARRAY_SIZE 8
|
||||||
|
char GArray[ARRAY_SIZE][ARRAY_SIZE];
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
void *ThreadF(void *letter) {
|
||||||
|
int i,j;
|
||||||
|
int LowLim, HighLim;
|
||||||
|
char letr;
|
||||||
|
|
||||||
|
letr = *(char *)letter;
|
||||||
|
if (letr == 'p') { // paremeter = p: fill lower half of array
|
||||||
|
LowLim = 0; HighLim = ARRAY_SIZE / 2;
|
||||||
|
}
|
||||||
|
else { // paremeter != p: fill upper half of array
|
||||||
|
LowLim = ARRAY_SIZE / 2; HighLim = ARRAY_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = LowLim; i < HighLim; i++) { // fill own half
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
GArray[i][j] = letr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE; i++) { // print whole array
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
printf("%c ", GArray[i][j]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
fflush(stdout);
|
||||||
|
pthread_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// Function: main(), parameter: none
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pthread_t thread1, thread2;
|
||||||
|
int i,j, pthr;
|
||||||
|
char letter1, letter2;
|
||||||
|
|
||||||
|
selectCPU(0); // run on CPU 0
|
||||||
|
|
||||||
|
// flip coin to select p or c first
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
srandom(tv.tv_usec); // evaluate seed
|
||||||
|
int head = (int)(random()) >> 7; // flip coin
|
||||||
|
head &= 0x1;
|
||||||
|
if (head) {
|
||||||
|
letter1 = 'p';
|
||||||
|
letter2 = 'c';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
letter1 = 'c';
|
||||||
|
letter2 = 'p';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE; i++)
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
GArray[i][j] = '-';
|
||||||
|
|
||||||
|
printf("\nArray vor Threads\n\n");
|
||||||
|
for (i = 0; i < ARRAY_SIZE; i++) {
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
printf("%c ", GArray[i][j]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
pthr = pthread_create(&thread1, NULL, ThreadF, (void *)&letter1);
|
||||||
|
if (pthr != 0) perror("Could not create thread");
|
||||||
|
pthr = pthread_create(&thread2, NULL, ThreadF, (void *)&letter2);
|
||||||
|
if (pthr != 0) perror("Could not create thread");
|
||||||
|
|
||||||
|
pthread_join(thread1, NULL);
|
||||||
|
pthread_join(thread2, NULL);
|
||||||
|
|
||||||
|
printf("\n... nach Threads\n");
|
||||||
|
for (i = 0; i < ARRAY_SIZE; i++) {
|
||||||
|
for (j = 0; j < ARRAY_SIZE; j++)
|
||||||
|
printf("%c ", GArray[i][j]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# *************************************************************
|
||||||
|
# Original Autor: M. Thaler (Modul BSY)
|
||||||
|
# *************************************************************
|
||||||
|
|
||||||
|
CMP= gcc -std=gnu99 -pthread
|
||||||
|
CMPFLAGS= -Wall
|
||||||
|
LDFLAGS=
|
||||||
|
EXENAME1= ProcA9.e
|
||||||
|
FNAM1= ProcA9.o selectCPU.o
|
||||||
|
LIBNAME=
|
||||||
|
|
||||||
|
$(EXENAME1): $(FNAM1)
|
||||||
|
$(CMP) $(FNAM1) $(LDFLAGS) $(LIBNAME) -o $@
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
.cc.o:
|
||||||
|
$(CMP) -c $(CMPFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXENAME1)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@make clean
|
||||||
|
@make
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
//******************************************************************************
|
||||||
|
// File: setCPU.c
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
#include <sched.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
|
||||||
|
void selectCPU(unsigned int n) {
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
if (n >= sysconf(_SC_NPROCESSORS_ONLN)) {
|
||||||
|
printf("CPU %d not availble\n", n);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
sched_getaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||||
|
CPU_ZERO(&cpuset);
|
||||||
|
CPU_SET(n, &cpuset);
|
||||||
|
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
void selectCPU(unsigned int n) {
|
||||||
|
printf("Cannot set single CPU on OSX\n ... continue anyway");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
//******************************************************************************
|
||||||
|
// File: setCPU.h
|
||||||
|
// Original Author: M. Thaler (Modul BSY)
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
#ifndef SET_CPUS_HEADER_FILE
|
||||||
|
#define SET_CPUS_HEADER_FILE
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
void selectCPU(unsigned int n);
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue