Difference between revisions of "Coding Contest 25 novembre 2016"
m (→Esercizio 4) |
|||
Line 31: | Line 31: | ||
fdf7b609e470c43a32a50801e76e78c32aebfbb1 main.tar.gz [[User:Alexp|Alexp]] ([[User talk:Alexp|talk]]) 17:22, 25 November 2016 (CET) | fdf7b609e470c43a32a50801e76e78c32aebfbb1 main.tar.gz [[User:Alexp|Alexp]] ([[User talk:Alexp|talk]]) 17:22, 25 November 2016 (CET) | ||
+ | |||
+ | In seguito il codice dell'esercizio --[[User:Alexp|Alexp]] ([[User talk:Alexp|talk]]) 13:50, 8 December 2016 (CET) : | ||
+ | <syntaxhighlight lang=C> | ||
+ | #include <unistd.h> | ||
+ | #include <stdio.h> | ||
+ | #include <signal.h> | ||
+ | #include <errno.h> | ||
+ | #include <sys/wait.h> | ||
+ | |||
+ | #define PID 6300 | ||
+ | |||
+ | void do_something(){ | ||
+ | //print something | ||
+ | printf("---doing something---\n"); | ||
+ | } | ||
+ | |||
+ | int main(int argc, char* argv[]) { | ||
+ | int sPID = PID; | ||
+ | if (argc > 1) { | ||
+ | sPID = atoi(argv[1]); | ||
+ | } | ||
+ | pid_t pid; | ||
+ | if (getpid() == sPID) { | ||
+ | //if sPID matched | ||
+ | printf("GOT PID (%d)!\n", sPID); | ||
+ | //do something | ||
+ | do_something(); | ||
+ | } else { | ||
+ | if (kill(sPID, 0) != 0 && errno == ESRCH) { | ||
+ | //while generated child has wrong sPID | ||
+ | while ((pid = fork()) != sPID) { | ||
+ | //if child | ||
+ | if (pid == 0) { | ||
+ | if (getpid() == sPID) { | ||
+ | printf("GOT PID (%d)!\n", sPID); | ||
+ | //do something | ||
+ | do_something(); | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | //if parent and error occoured | ||
+ | else if (pid == -1) { | ||
+ | printf("Error: process table is full.\n"); | ||
+ | break; | ||
+ | } | ||
+ | //if parent and no error occoured | ||
+ | else { | ||
+ | //wait for child process to finish | ||
+ | wait(NULL); | ||
+ | } | ||
+ | } | ||
+ | //we must wait for the last child | ||
+ | if (pid == sPID) { | ||
+ | printf("Waiting for the last child."); | ||
+ | wait(NULL); | ||
+ | } | ||
+ | } else { | ||
+ | printf("Impossible to get pid %d(another process has it).\n", sPID); | ||
+ | } | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
== Esercizio 4 == | == Esercizio 4 == |
Latest revision as of 13:50, 8 December 2016
Esercizio 1
scrivere un programma che passato come parametro il path di una directory (cwd se manca il paramtro) stampi il path relativo di tutti i file con nome palindromo presenti nel sottoalbero.
2720c84e673c75c20a27a07ffcd6826b31c8babc esercizio1.c Leonardo (talk) 17:23, 25 November 2016 (CET)
86aca4384a296bf12c69541fc5418fe4b6656e0d es1.c Fabio.capucci (talk) 17:30, 25 November 2016 (CET)
071fccfe63b8121f951444cb57001ccdd4ec02d0 Es1.c FilippoB (talk) 17:31, 25 November 2016 (CET)
235f2414cfe5b81973b1d388ce9431aa02b5f305 MatteoC (talk) 17:43, 25 November 2016 (CET)
168d3422b92fc78519e19d6a8e156b260a7798a6 testdir.c Tamino (talk) 18:06, 25 November 2016 (CET)
Esercizio 2
lancia tutti gli eseguibili della directory passata come primo paramtro e concatena gli output. (i parametri rimanenti devono essere passati a tutti gli eseguibili)
lanciatutti dir 1 2 3
se nella directory dir sono presenti a, b e c (eseguibili) lancia a 1 2 3', b 1 2 3, c 1 2 3
Esercizio 3
Scrivere un programma che deve ottenere il pid passato come parametro. indicare se e' impossibile
fdf7b609e470c43a32a50801e76e78c32aebfbb1 main.tar.gz Alexp (talk) 17:22, 25 November 2016 (CET)
In seguito il codice dell'esercizio --Alexp (talk) 13:50, 8 December 2016 (CET) :
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#define PID 6300
void do_something(){
//print something
printf("---doing something---\n");
}
int main(int argc, char* argv[]) {
int sPID = PID;
if (argc > 1) {
sPID = atoi(argv[1]);
}
pid_t pid;
if (getpid() == sPID) {
//if sPID matched
printf("GOT PID (%d)!\n", sPID);
//do something
do_something();
} else {
if (kill(sPID, 0) != 0 && errno == ESRCH) {
//while generated child has wrong sPID
while ((pid = fork()) != sPID) {
//if child
if (pid == 0) {
if (getpid() == sPID) {
printf("GOT PID (%d)!\n", sPID);
//do something
do_something();
}
break;
}
//if parent and error occoured
else if (pid == -1) {
printf("Error: process table is full.\n");
break;
}
//if parent and no error occoured
else {
//wait for child process to finish
wait(NULL);
}
}
//we must wait for the last child
if (pid == sPID) {
printf("Waiting for the last child.");
wait(NULL);
}
} else {
printf("Impossible to get pid %d(another process has it).\n", sPID);
}
}
return 0;
}
Esercizio 4
Trovare i file di contenuto uguale nella directory corrente e convertirli in link dello stesso file.
Esempio di soluzione dell'esercizio Renzo (talk) 09:06, 6 December 2016 (CET). (in aula sembrava avere un bug ma non era vero. Alcuni file in /tmp non sono stati convertiti in link perché appartenevano ad altro utente).
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <libgen.h>
#include <errno.h>
#include <dirent.h>
#include <mhash.h>
#include <sys/types.h>
#include <sys/stat.h>
struct file {
struct file *next;
unsigned char hash[20];
char *name;
};
struct file *head;
static int ckcontents(int fd1, int fd2) {
char buf1[BUFSIZ],buf2[BUFSIZ];
ssize_t n1, n2;
do {
n1 = read(fd1, buf1, BUFSIZ);
n2 = read(fd2, buf2, BUFSIZ);
} while (n1 == n2 && n1 > 0 && memcmp(buf1, buf2, n2 == 0));
return n1 == n2;
}
static int cksize(int fd1, int fd2) {
struct stat st1, st2;
return
fstat(fd1, &st1) == 0 &&
fstat(fd2, &st2) == 0 &&
st1.st_size == st2.st_size;
}
int filecmp(char *path1, char *path2) {
int fd1 = open(path1, O_RDONLY);
int fd2 = open(path2, O_RDONLY);
int rval =
fd1 >= 0 && fd2 >=0 && cksize(fd1, fd2) && ckcontents(fd1, fd2);
close(fd1);
close(fd2);
return rval;
}
#if 0
void printhash(unsigned char * hash) {
int i;
for (i = 0; i < mhash_get_block_size(MHASH_SHA1); i++)
printf("%.2x", hash[i]);
}
#endif
void compute_sha1sum(char *path, char *hash) {
int fd;
MHASH td;
if ((fd = open(path, O_RDONLY)) >= 0) {
if ((td = mhash_init(MHASH_SHA1)) != MHASH_FAILED) {
ssize_t n;
char buf[BUFSIZ];
while ((n = read(fd, buf, BUFSIZ)) > 0)
mhash(td, buf, n);
mhash_deinit(td, hash);
}
close(fd);
}
}
static void check_n_link(char *name) {
struct file **scan;
unsigned char hash[20];
compute_sha1sum(name, hash);
for (scan = &head; *scan != NULL; scan = &((*scan) -> next)) {
//printhash((*scan)->hash); printf(" - "); printhash(hash); printf("\n");
if (memcmp((*scan)->hash, hash, 20) == 0 &&
filecmp((*scan)->name, name)) {
unlink(name);
link((*scan)->name, name);
printf("%s and %s have the same contents\n", (*scan)->name, name);
return;
}
}
*scan = malloc(sizeof(struct file));
if (*scan) {
(*scan)->next = NULL;
memcpy((*scan)->hash, hash, 20);
(*scan)->name = name;
//printf("%s\n",name);
}
}
static void freefilelist() {
while (head) {
struct file *delenda;
delenda = head;
head = head->next;
free(delenda);
}
}
void err_exit(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(2);
}
static int regular_only(const struct dirent *d) {
const char *name = d->d_name;
struct stat st;
return stat(name, &st) == 0 && S_ISREG(st.st_mode);
}
int main(int argc, char *argv[]) {
struct dirent **list;
int n;
int i;
n = scandir(".", &list, regular_only, alphasort);
if (n > 0) {
for (i=0; i<n; i++) {
char *name = list[i]->d_name;
check_n_link(name);
}
freefilelist();
for (i=0; i<n; i++)
free(list[i]);
free(list);
}
}