So i'm working on linux and my question is how make a program accept arguments in execution like this one:
./program am i
Also both functions work the same way at the moment, because i'm struggling with getting only this line:
(expected result of show_info_who_am_i)
Kamil pts/0 2015-11-12 10:14 (:0)
instead of both of them:
(result of show_info_who)
Kamil tty2 2015-11-12 10:13 (:0)
Kamil pts/0 2015-11-12 10:14 (:0)
#include <stdio.h>
#include <utmp.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#define SHOWHOST /* include remote machine on output */
show_info_who( struct utmp *utbufp )
{
if(utbufp->ut_type > 4){
time_t czas = utbufp->ut_time;
char buf[80];
struct tm* timeinfo = localtime(&czas);
printf("%-8.8s", utbufp->ut_name); /* the logname */
printf(" "); /* a space */
printf("%-8.8s", utbufp->ut_line); /* the tty */
printf(" "); /* a space */
strftime(buf, 80, "%F %R" , timeinfo);
printf("%s", buf);
printf(" "); /* a space */
#ifdef SHOWHOST
printf("(%s)", utbufp->ut_host); /* the host */
#endif
printf("\n"); /* newline */
}
}
show_info_who_am_i( struct utmp *utbufp )
{
if(utbufp->ut_type > 4){
time_t czas = utbufp->ut_time;
char buf[80];
struct tm* timeinfo = localtime(&czas);
printf("%-8.8s", utbufp->ut_name); /* the logname */
printf(" "); /* a space */
printf("%-8.8s", utbufp->ut_line); /* the tty */
printf(" "); /* a space */
strftime(buf, 80, "%F %R" , timeinfo);
printf("%s", buf);
printf(" "); /* a space */
#ifdef SHOWHOST
printf("(%s)", utbufp->ut_host); /* the host */
#endif
printf("\n"); /* newline */
}
}
int main(int argc, char *argv[])
{
struct utmp current_record; /* read info into here */
int utmpfd; /* read from this descriptor */
int reclen = sizeof(current_record);
if ( (utmpfd = open(UTMP_FILE, O_RDONLY)) == -1 ){
perror( UTMP_FILE ); /* UTMP_FILE is in utmp.h */
exit(1);
}
//char am[22] = "am"; /* test */
//char i[22] = "i"; /* test */
//printf("%s,%s\n\n", am,i); /* test */
//printf("%s", argv[1]);
if(argv[1]== "am"){
if(argv[2]== "i"){
while ( read(utmpfd, ¤t_record, reclen) == reclen )
show_info_who_am_i(¤t_record);
}
}
else{
while ( read(utmpfd, ¤t_record, reclen) == reclen )
show_info_who(¤t_record);
}
//printf("%s,%s", argv[1], argv[2]); /* test */
close(utmpfd);
return 0; /* went ok */
}
Related
Current uni student and need help writing a c program that displays the contents and all information in a directory.
The listing should have the filename, mode, links, user, group size and modtime.
this is what i have completed:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
void do_ls(char [], struct stat *);
void show_stat_info(char [], struct stat *);
main(int ac, char *av[])
{
struct stat info;
if ( ac == 1 )
do_ls( ".",&info );
else
while ( --ac ){
printf("%s:\n", *++av );
do_ls( *av,&info );
}
}
void do_ls( char dirname[], struct stat *buf )
/*
* list files in directory called dirname
*/
{
DIR *dir_ptr; /* the directory */
struct dirent *direntp; /* each entry */
if ( ( dir_ptr = opendir( dirname ) ) == NULL )
fprintf(stderr,"ls1: cannot open %s\n", dirname);
else
{
while ( ( direntp = readdir( dir_ptr ) ) != NULL )
{
printf("%s\n", direntp->d_name );
printf(" mode: %o\n", buf->st_mode); /* type + mode */
printf(" links: %d\n", buf->st_nlink); /* # links */
printf(" user: %d\n", buf->st_uid); /* user id */
printf(" group: %d\n", buf->st_gid); /* group id */
printf(" size: %d\n", buf->st_size); /* file size */
printf("modtime: %d\n", buf->st_mtime); /* modified */
//printf(" name: %s\n", fname ); /* filename */
}
closedir(dir_ptr);
}
}
right now it only lists the files inside a directory but all the details come back as zero
when I pass a directory to the function it will say "can not open filename"
This is what I am trying to achieve:
if no argument is passed through the program will print all the names and the details of the current directory
if a directory is passed through the program will print the information for all files inside the directory
I removed the stat pointer argument, used early return to simplify code, and called stat on each path which is build by combining the directory and file name (crudely), also fixed the format strings:
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
void do_ls(char dirname[]) {
DIR *dir_ptr;
if(!(dir_ptr = opendir( dirname ))) {
fprintf(stderr,"ls1: cannot open %s\n", dirname);
return;
}
struct dirent *direntp;
while((direntp = readdir(dir_ptr))) {
struct stat buf;
char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s/%s", dirname, direntp->d_name);
if(stat(path, &buf)) {
fprintf(stderr,"stat failed\n");
break;
}
printf("%s\n", direntp->d_name );
printf(" mode: %o\n", buf.st_mode); /* type + mode */
printf(" links: %ld\n", buf.st_nlink); /* # links */
printf(" user: %d\n", buf.st_uid); /* user id */
printf(" group: %d\n", buf.st_gid); /* group id */
printf(" size: %ld\n", buf.st_size); /* file size */
printf("modtime: %ld\n", buf.st_mtime); /* modified */
printf(" name: %s\n", path ); /* filename */
}
closedir(dir_ptr);
}
int main(int ac, char *av[]) {
if(ac == 1) {
do_ls(".");
return 0;
}
while(--ac) {
printf("%s:\n", *++av);
do_ls(*av);
}
return 0;
}
I am trying to cat some file into another new files, but to my surprise its not working.
Able to do the same if i execute the same command on terminal, but through system call, it not working.
I just need a new set of eyes to look and point out the problem please
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#define COMMON_COMMAND "cd %s;cat %s >> %s"
#define RPATH "/home/spark/R/"
#define R_CERTIFICATE_NOT_FOUND 2
#define RESULT_NOT_FOUND_FILE 5
#define DIR_CERTIFICATE_NOT_FOUND 6
#define RESULT_SUCCESS 0
#define BUFFER_SIZE 1000
/*Final file*/
#define COMMON_FILE "common_file_"
static int prepare_FinFiles(const char *rpath,char *common_file);
static int ReadFiles(const char *path,char *common_file);
int main()
{
char Finfile[BUFFER_SIZE] = {0};
char cmd[50] = {0};
struct timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec);
prepare_FinFiles(RPATH,Finfile);
strcpy(cmd,"cat ");
strcat(cmd,Finfile);
printf(" cmd output ==> \n");
system(cmd);
return 0;
}
static int prepare_FinFiles(const char *rpath,char *common_file)
{
char command[BUFFER_SIZE] = {0};
char temp_files[BUFFER_SIZE] = {0};
int32_t count_no_files = 0;
char cmd[BUFFER_SIZE] = {0};
sprintf(common_file, "%s%d%s", "/home/spark/"COMMON_FILE,random(),".txt");
strcpy(cmd,"touch ");
strcat(cmd, common_file);
system(cmd);
if( ReadFiles(rpath,common_file) == RESULT_NOT_FOUND_FILE)
{
return R_CERTIFICATE_NOT_FOUND;
}
else if(retVal == DIR_CERTIFICATE_NOT_FOUND)
{
printf("dir not found\n");
return DIR_CERTIFICATE_NOT_FOUND;
}
else
{
printf("R read success\n");
char Finfile[BUFFER_SIZE] = {0};
char cmd[50] = {0};
strcpy(cmd,"cat ");
strcat(cmd,common_file);
printf("cmd : %s\n",cmd);
printf("The return value is: %d\n", WEXITSTATUS(system(cmd)));
}
}
static int32_t ReadFiles(const char *path,char *common_file)
{
DIR *dir = opendir(path);
struct dirent *dp;
char command[BUFFER_SIZE] = {0};
char temp_files[BUFFER_SIZE] = {0};
int count_no_files =0;
printf("Reading from %s path\n", path);
if(!dir)
{
return DIR_CERTIFICATE_NOT_FOUND;
}
else
{
while ((dp = readdir(dir)) != NULL)
{
if( strncmp(dp->d_name,".",strlen(".")) &&
strncmp(dp->d_name,"..",strlen(".."))
)
{
strncat(temp_files,dp->d_name,strlen(dp->d_name));
strncat(temp_files," ",strlen(" "));
count_no_files++;
}
}
if(count_no_files == 0)
{
return RESULT_NOT_FOUND_FILE;
}
else
{
memset(command,0,sizeof(command));
sprintf(command, COMMON_COMMAND, path,temp_files,common_file);
printf("command = %s\n", command);
return RESULT_SUCCESS;
}
}
}
output
Reading from /home/spark/R/ path
command = cd /home/spark/R/;cat file1.txt >> /home/spark/R/common_file_931058571.txt
R read success
cmd : cat /home/spark/R/common_file_931058571.txt
The return value is: 0
but through system call, it not working
Because you do not call system at all.
Your code contains 3 calls to system:
// in main
system(cmd); // cmd contains "cat /home/spark/common_file_<random>.txt"
// in prepare_FinFile
system(cmd); // cmd contains "touch /home/spark/common_file_<random>.txt"
...
printf("cmd : %s\n",cmd);
printf("The return value is: %d\n", WEXITSTATUS(system(cmd)));
// cmd contains "cat /home/spark/R/common_file_931058571.txt"
The command in question would be this:
printf("command = %s\n", command);
// command contains "cd /home/spark/R/;cat file1.txt >> /home/spark/R/common_file_931058571.txt"
return RESULT_SUCCESS;
But you never execute it. You just print it.
I want to display my two attributes from the structure stat
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
Here is my code that i try to display the last time access and the last time of last modification of folder/file
struct tm *time;
char buffer[200];
time = localtime(file_info.st_atime);
strftime(buffer, sizeof(buffer), "%d.%m.%Y %H:%M:%S", time);
printf("%s\n", buffer);
time = localtime(file_info.st_mtime);
strftime(buffer, sizeof(buffer), "%d.%m.%Y %H:%M:%S", time);
printf("%s\n", buffer);
I want to display like human readble time and date like 15.03.1952 23:11:34 of a folder/file info that has been last modifed or access in linux
This deviates a bit from your code in terms of style, but perhaps it's helpful?
#include <time.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
char* formatdate(char* str, time_t val)
{
strftime(str, 36, "%d.%m.%Y %H:%M:%S", localtime(&val));
return str;
}
int main()
{
int errno;
const char* filename;
filename = "stat.c";
errno = 0;
struct stat *file_info = malloc(sizeof(struct stat));
if (lstat(filename, file_info) != 0) {
perror("Error");
exit(1);
}
char date[36];
printf("Access: %s\n", formatdate(date, file_info->st_atime));
printf("Modify: %s\n", formatdate(date, file_info->st_mtime));
printf("Change: %s\n", formatdate(date, file_info->st_ctime));
free(file_info);
return 0;
}
char buffer[200];
printf("Access : %s\n", formatdate(buffer, file_info.st_atime));
printf("Modify : %s\n", formatdate(buffer, file_info.st_mtime));
printf("\n\n");
char *formatdate(char *buff, time_t val)
{
strftime(buff,200, "%d.%m.%Y %H:%M:%S", localtime(&val));
return buff;
}
And this is the answer that i was looking for thanks again.
Try this: printf("%s", asctime(localtime(&buffer.st_mtime)));
I need to print the names of all files in the current directory.
but I must do it only with system calls, so I have the SYS_OPEN, SYS_GETDENTS, SYS_READ etc. I'm working on Ubuntu.
How can I do it?
I tried to use this:
system_call(SYS_OPEN, ".", 0, 0777);
and then to READ from and write to STDOUT.. but it's not working.
** I cannot use the standard library.
Thank you!
EDIT:
an example code:
** there is a file in assembly, with the function "system call" that do the call.
#include "util.h"
#define SYS_WRITE 4
#define SYS_OPEN 5
#define SYS_CLOSE 6
#define SYS_READ 3
#define SYS_LSEEK 19
#define SYS_GETDENTS 141
#define BUF_SIZE 1024
#define STDOUT 1
struct linux_dirent {
long d_ino;
int d_off;
unsigned short d_reclen;
char d_name[];
};
int main (int argc , char* argv[], char* envp[])
{
int fd=0;
int nread;
char * nread_str;
char buf[BUF_SIZE];
struct linux_dirent *d;
int bpos;
char d_type;
fd=system_call(SYS_OPEN,".", 0 , 0);
for ( ; ; ) {
nread = system_call(SYS_GETDENTS, fd, buf, BUF_SIZE);
if (nread == -1)
system_call(SYS_WRITE,STDOUT, "error-getdents",BUF_SIZE);
if (nread == 0)
break;
system_call(SYS_WRITE,STDOUT, "--------------- nread=%d ---------------\n",100);
nread_str=itoa(nread);
system_call(SYS_WRITE,STDOUT, nread_str,100);
system_call(SYS_WRITE,STDOUT, "i-node# file type d_reclen d_off d_name\n",100);
for (bpos = 0; bpos < nread;) {
d = (struct linux_dirent *) (buf + bpos);
/* printf("%8ld ", d->d_ino);**/
d_type = *(buf + bpos + d->d_reclen - 1);
/* printf("%4d %10lld %s\n", d->d_reclen,
(long long) d->d_off, (char *) d->d_name);**/
bpos += d->d_reclen;
}
}
}
return 0;
}
#include <fstream>
#include <iostream>
#include <string>
#include <dirent.h>
using namespace std;
int main()
{
DIR *dir;
struct dirent *ent;
if ((dir = opendir ("c:\\")) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
printf ("%s\n", ent->d_name);
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return EXIT_FAILURE;}
}
Read the manual pages for opendir etc.
See http://linux.die.net/man/3/opendir
Please help me find this " segmentation fault:11 ". argv input looking fine. By the way this a dining philosopher problem. It was working hour ago but on minix machine but now on Unix machine it doesn't run. Please help me with the stupid error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#define N 5
#define REPETITIONS 10
#define EATTIME 3000000
#define THINKTIME EATTIME * 3
#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define HUNGRY 1
#define EATING 2
#define THINKING 0
#define mutex "mutex"
#define mutexLock "mutex.lock"
#define Output "output"
#define states "states"
#define statesLock "states.lock"
#define binarySemaphore "semaphore"
#define binarySemaphoreLock "semaphore.lock"
#define up(lock) unlink(lock)
#define down(lock1,lock2) while(link(lock1,lock2)== -1);
void readFile(int numberFromFile[],char *file); /* declaring readfile() */
void writeFile(int numberToFile[],char *file); /* declaring writeFile() */
void setPhilosopher(int i,int number); /* declaring setPhilosopher() */
void take_Forks(int i); /* declaring take_Forks() */
void downPhilosopher(int i); /* declaring downPhilosopher() */
void thinking(int j); /* declaring thinking() */
void setState(int i,int number); /* declaring setState() */
void test(int i); /* declaring test() */
void philosopher(int i); /* declaring philosopher() */
void eating(int j); /* declaring eating() */
void put_Forks(int i); /* declaring put_Forks() */
int argNo(char *argv); /* declaring arg number() */
int main(int args,char *argv[])
{
int i; /* declaring i*/
i = argNo(argv[1]); /* assigning argument number to i*/
if((i < 0) || (i >= N))
{
fprintf(stderr,"Input not valid\n"); /* displays an error message*/
/* when number is less than 0*/
/* number is more than N */
}
else
{
if((i < N) && (i >= 0)) /* else calls the philosopher function*/
philosopher(i); /* and passes the number to it */
// printf("Hello %d\n", i);
}
}
int argNo(char *argv)
{
int number; /* declaring number*/
sscanf(argv,"%d",&number); /* gets number from the command line */
return number; /* return number*/
}
void philosopher(int i)
{
int j; /* declaring j*/
for(j = 0; j < REPETITIONS; j++)
{
thinking(i); /* invoking thinking function*/
take_Forks(i); /* invoking take_Forks function*/
eating(i); /* invoking eating function*/
put_Forks(i); /* invoking put_Forks function*/
}
}
void thinking(int j)
{
int i,pid; /* declaring i and pid */
FILE *fp = fopen(Output,"a+"); /* creating and opening a file*/
pid = getpid(); /* getting process id*/
for(i = 0;i < THINKTIME ; i++); /* philosopher is thinking */
fclose(fp); /* closing the file*/
}
void take_Forks(int i)
{
down(mutex,mutexLock); /* entering critical region*/
setState(i,HUNGRY); /* setting State to hungry */
test(i); /* invoking test function*/
up(mutexLock); /* exit critical region*/
downPhilosopher(i); /* invoking downPhilosopher function*/
}
void eating(int j)
{
int i; /* declaring i as an int */
int pid = getpid(); /* getting the process ID */
FILE *fp = fopen(Output,"a+"); /* creating and opening file */
fprintf(fp,"%d %d eating\n",pid,j); /* writing a message to a file*/
fprintf(stdout,"%d %d eating\n",pid,j); /* displaying to stdout*/
fflush(fp); /* flushing file*/
for(i = 0; i < EATTIME; i++); /* philosopher eating*/
fprintf(fp,"%d %d done eating\n",pid,j); /* writing message to file*/
fprintf(stdout,"%d %d done eating\n",pid,j); /* displaying to stdout*/
fflush(fp); /* flushing file*/
fclose(fp); /* closing file*/
}
void put_Forks(int i)
{
down(mutex,mutexLock); /* entering critical region*/
setState(i,THINKING); /* setting state to thinking */
test(LEFT); /* checks if left and right */
test(RIGHT); /* philosophers want to eat */
up(mutexLock); /* exit critical region*/
}
void downPhilosopher(int i)
{
int semaphores[N]; /* declaring semaphore array*/
do
{
readFile(semaphores,binarySemaphore); /* reading binarySemaphore into semaphore */
}while(semaphores[i] == 0); /* spin locks if semaphore is 0 */
setPhilosopher(i,0); /* setting the philosopher's state to 0*/
}
void setState(int i,int number)
{
int theStates[N]; /* declaring States array*/
down(states,statesLock); /* enters critical region*/
readFile(theStates,states); /* read states from file*/
theStates[i] = number; /* changing the state */
writeFile(theStates,states); /* writes a state to a file*/
up(statesLock); /* exit critical region*/
}
void test(int i)
{
int theStates[N]; /* declaring theStates array*/
down(states,statesLock); /* enters critical region*/
readFile(theStates,states); /* read file states*/
up(statesLock); /* exit critical region*/
if(theStates[i] == HUNGRY && theStates[LEFT] != EATING &&
theStates[RIGHT] != EATING)
{
setState(i,EATING); /* set the state of philosopher to eating*/
setPhilosopher(i,1); /* set the semaphore to 1*/
}
}
void setPhilosopher(int i,int number)
{
int semaphores[N]; /* declaring semaphores[]*/
down(binarySemaphore,binarySemaphoreLock); /* enters critical region*/
readFile(semaphores,binarySemaphore); /* reading from file*/
semaphores[i] = number; /* updates the semaphore array*/
writeFile(semaphores,binarySemaphore); /* writing semaphore to file*/
up(binarySemaphoreLock); /* exit critical region*/
}
void readFile(int numberFromFile[],char *file)
{
FILE *fp = fopen(file,"r"); /* creating and opening file*/
int i; /* declaring i as int */
for(i = 0; i< N; i++)
fscanf(fp,"%d",&numberFromFile[i]); /* reading from file into*/
/* numberFromFile array*/
fclose(fp); /* closing the file*/
}
void writeFile(int numberToFile[],char *file)
{
FILE *fp = fopen(file,"w"); /* creating and opening a file */
int i; /* declaring i as int */
for(i = 0; i< N; i++)
fprintf(fp,"%d\n",numberToFile[i]); /* writing */
/* numberToFile array to file*/
fclose(fp); /* closing the file*/
}
Your logic here doesn't validate the input completely:
i = argNo(argv[1]);
I can replicate a segfault if i provide no parameter where your code is expecting a number as the first argument on the command line.
A quick fix may be to check the size of argc (or "args" in your code) before trying to reference argv[1] (which may not have been supplied).
or try to run under gdb
$ gcc -g myprogram.c
(gdb) run
Starting program: /home/b3h3m0th/a.out
Program received signal SIGSEGV, Segmentation fault.
rawmemchr () at ../sysdeps/i386/rawmemchr.S:116
116 ../sysdeps/i386/rawmemchr.S: No such file or directory
try to search a bug report about that.
At this place the comment does not match the code:
void readFile(int numberFromFile[],char *file)
{
/* FILE *fp = fopen(file,"r"); /* creating and opening file*/
FILE *fp = fopen(file,"w+"); /* creating and opening file*/
A few notes:
it is a good habit to have preprocessor macros in ALLCAPS, this makes them easy to recognise
(global) constants with 1 letter names (N) are hard to search
always parenthesize macro arguments (LEFT,RIGHT)
never make macros refer to variable names,(LEFT,RIGHT)
(maybe) except for some trivial stuff (stderr, logfiles, global variables)
(I sinned to this rule, using the filo_count variable in the macros ;-)
Changed the mode for fopen to "w+",
Plus a few changes to main (added fork() ), plus removed lots of silly comments.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#define MAX_PHILOSOPHER 50
#define REPETITIONS 1
#define EATTIME 3000000
#define THINKTIME (EATTIME * 3)
#define LEFT(i) (((i)+filo_count-1)%filo_count)
#define RIGHT(i) (((i)+1)%filo_count)
#define HUNGRY 1
#define EATING 2
#define THINKING 0
#define MUTEX_FILENAME "mutex"
#define MUTEX_FILE_LOCK "mutex.lock"
#define LOG_FILENAME "output"
#define STATE_FILENAME "states"
#define STATE_FILE_LOCK "states.lock"
#define SEMAPHORE_FILENAME "semaphore"
#define SEMAPHORE_FILE_LOCK "semaphore.lock"
#define up(lock) unlink(lock)
#define down(file,lock) do {;} while(link(file,lock)== -1)
void readFile(int array[],char *file);
void writeFile(int array[],char *file);
void setPhilosopher(int i,int number);
void take_Forks(int i);
void downPhilosopher(int i);
void thinking(int j);
void setState(int i,int number);
void test(int i);
void philosopher(int i);
void eating(int j);
void put_Forks(int i);
int argNo(char *argv);
unsigned filo_count=0;
int main(int argc,char *argv[])
{
int i;
fprintf(stderr,"argc was %d\n", argc);
i = argv[1] ? argNo(argv[1]): -1;
if (i < 0 || i >= MAX_PHILOSOPHER)
{
fprintf(stderr,"Input not valid\n");
exit (1);
}
filo_count=i;
if (0) {
FILE *fp;
fp = fopen(MUTEX_FILENAME, "w"); fclose(fp);
fp = fopen(STATE_FILENAME, "w"); fclose(fp);
fp = fopen(SEMAPHORE_FILENAME, "w"); fclose(fp);
}
for(i=0; i < filo_count ; i++ ) {
if (fork()) continue;
/* philosopher is a child process */
philosopher(i);
break;
}
fprintf(stderr,"%d Dead.\n", getpid() );
return 0;
}
int argNo(char *argv)
{
int number;
sscanf(argv,"%d",&number);
return number;
}
void philosopher(int i)
{
int j;
for(j = 0; j < REPETITIONS; j++)
{
thinking(i);
take_Forks(i);
eating(i);
put_Forks(i);
}
}
void thinking(int j)
{
int i,pid;
FILE *fp = fopen(LOG_FILENAME,"a+");
for(i = 0;i < THINKTIME ; i++); /* burn some CPU */
fclose(fp);
}
void take_Forks(int i)
{
down(MUTEX_FILENAME,MUTEX_FILE_LOCK); /* enter critical region*/
setState(i,HUNGRY);
test(i);
up(MUTEX_FILE_LOCK);
downPhilosopher(i);
}
void eating(int j)
{
int i;
int pid = getpid();
FILE *fp = fopen(LOG_FILENAME,"a+");
fprintf(fp,"%d %d eating\n",pid,j);
fprintf(stdout,"%d %d eating\n",pid,j);
fflush(fp);
for(i = 0; i < EATTIME; i++); /* Spin idle while eating */
fprintf(fp,"%d %d done eating\n",pid,j);
fprintf(stdout,"%d %d done eating\n",pid,j);
fclose(fp);
}
void put_Forks(int i)
{
down(MUTEX_FILENAME,MUTEX_FILE_LOCK); /* enter critical region*/
setState(i,THINKING);
test(LEFT(i)); /* checks if left and right */
test(RIGHT(i)); /* philosophers want to eat */
up(MUTEX_FILE_LOCK);
}
void downPhilosopher(int i)
{
int semaphores[MAX_PHILOSOPHER];
do
{
readFile(semaphores,SEMAPHORE_FILENAME);
} while (semaphores[i] == 0); /* spin locks if semaphore is 0 */
setPhilosopher(i,0);
}
void setState(int i,int number)
{
int theStates[MAX_PHILOSOPHER];
down(STATE_FILENAME,STATE_FILE_LOCK); /* enters critical region*/
readFile(theStates,STATE_FILENAME);
theStates[i] = number;
writeFile(theStates,STATE_FILENAME); /* writes a state to a file*/
up(STATE_FILE_LOCK);
}
void test(int i)
{
int theStates[MAX_PHILOSOPHER];
down(STATE_FILENAME,STATE_FILE_LOCK); /* enters critical region*/
readFile(theStates,STATE_FILENAME);
up(STATE_FILE_LOCK);
if(theStates[i] == HUNGRY
&& theStates[LEFT(i)] != EATING
&& theStates[RIGHT(i)] != EATING)
{
setState(i,EATING);
setPhilosopher(i,1);
}
}
void setPhilosopher(int i,int number)
{
int semaphores[MAX_PHILOSOPHER];
down(SEMAPHORE_FILENAME,SEMAPHORE_FILE_LOCK); /* enter critical region*/
readFile(semaphores,SEMAPHORE_FILENAME);
semaphores[i] = number;
writeFile(semaphores,SEMAPHORE_FILENAME);
up(SEMAPHORE_FILE_LOCK);
}
void readFile(int array[],char *file)
{
FILE *fp = fopen(file,"w+"); /* creating and opening file*/
int i;
for(i = 0; i< filo_count; i++) {
if ( 1 > fscanf(fp,"%d",&array[i]) ) array[i] = -1;
}
fclose(fp);
}
void writeFile(int array[],char *file)
{
FILE *fp = fopen(file,"w"); /* creating and opening a file */
int i;
for(i = 0; i< filo_count; i++) {
fprintf(fp,"%d\n",array[i]);
}
fclose(fp);
}
I have not proven the above code correct, only that it works ;-)