1/*
2 * Create a squashfs filesystem.  This is a highly compressed read only
3 * filesystem.
4 *
5 * Copyright (c) 2013
6 * Phillip Lougher <phillip@squashfs.org.uk>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2,
11 * or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * unsquashfs_info.c
23 */
24
25#include <pthread.h>
26#include <sys/ioctl.h>
27#include <unistd.h>
28#include <signal.h>
29#include <sys/time.h>
30#include <stdio.h>
31#include <math.h>
32#include <stdarg.h>
33#include <errno.h>
34#include <stdlib.h>
35#include <dirent.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <string.h>
39
40#include "squashfs_fs.h"
41#include "unsquashfs.h"
42#include "error.h"
43
44static int silent = 0;
45char *pathname = NULL;
46
47pthread_t info_thread;
48
49
50void disable_info()
51{
52	if(pathname)
53		free(pathname);
54
55	pathname = NULL;
56}
57
58
59void update_info(char *name)
60{
61	if(pathname)
62		free(pathname);
63
64	pathname = name;
65}
66
67
68void dump_state()
69{
70	disable_progress_bar();
71
72	printf("Queue and cache status dump\n");
73	printf("===========================\n");
74
75	printf("file buffer read queue (main thread -> reader thread)\n");
76	dump_queue(to_reader);
77
78	printf("file buffer decompress queue (reader thread -> inflate"
79							" thread(s))\n");
80	dump_queue(to_inflate);
81
82	printf("file buffer write queue (main thread -> writer thread)\n");
83	dump_queue(to_writer);
84
85	printf("\nbuffer cache (uncompressed blocks and compressed blocks "
86							"'in flight')\n");
87	dump_cache(data_cache);
88
89	printf("fragment buffer cache (uncompressed frags and compressed"
90						" frags 'in flight')\n");
91	dump_cache(fragment_cache);
92
93	enable_progress_bar();
94}
95
96
97void *info_thrd(void *arg)
98{
99	sigset_t sigmask;
100	int sig, err, waiting = 0;
101
102	sigemptyset(&sigmask);
103	sigaddset(&sigmask, SIGQUIT);
104	sigaddset(&sigmask, SIGHUP);
105	sigaddset(&sigmask, SIGALRM);
106
107	while(1) {
108		err = sigwait(&sigmask, &sig);
109
110		if(err == -1) {
111			switch(errno) {
112			case EINTR:
113				continue;
114			default:
115				BAD_ERROR("sigwait failed "
116					"because %s\n", strerror(errno));
117			}
118		}
119
120		if(sig == SIGQUIT && !waiting) {
121			if(pathname)
122				INFO("%s\n", pathname);
123
124			/* set one second interval period, if ^\ received
125			   within then, dump queue and cache status */
126			waiting = 1;
127			alarm(1);
128		} else if (sig == SIGQUIT) {
129			dump_state();
130		} else if (sig == SIGALRM) {
131			waiting = 0;
132		}
133	}
134}
135
136
137void init_info()
138{
139	pthread_create(&info_thread, NULL, info_thrd, NULL);
140}
141