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