]>
Dogcows Code - chaz/tar/blob - src/checkpoint.c
1 /* Checkpoint management for tar.
3 Copyright 2007, 2013-2014 Free Software Foundation, Inc.
5 This file is part of GNU tar.
7 GNU tar is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 GNU tar is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include "wordsplit.h"
23 #include <sys/ioctl.h>
25 #include "fprintftime.h"
27 enum checkpoint_opcode
38 struct checkpoint_action
40 struct checkpoint_action
*next
;
41 enum checkpoint_opcode opcode
;
49 /* Checkpointing counter */
50 static unsigned checkpoint
;
52 /* List of checkpoint actions */
53 static struct checkpoint_action
*checkpoint_action
, *checkpoint_action_tail
;
55 static struct checkpoint_action
*
56 alloc_action (enum checkpoint_opcode opcode
)
58 struct checkpoint_action
*p
= xzalloc (sizeof *p
);
59 if (checkpoint_action_tail
)
60 checkpoint_action_tail
->next
= p
;
62 checkpoint_action
= p
;
63 checkpoint_action_tail
= p
;
69 copy_string_unquote (const char *str
)
71 char *output
= xstrdup (str
);
72 size_t len
= strlen (output
);
73 if ((*output
== '"' || *output
== '\'')
74 && output
[len
-1] == *output
)
76 memmove (output
, output
+1, len
-2);
79 unquote_string (output
);
84 checkpoint_compile_action (const char *str
)
86 struct checkpoint_action
*act
;
88 if (strcmp (str
, ".") == 0 || strcmp (str
, "dot") == 0)
89 alloc_action (cop_dot
);
90 else if (strcmp (str
, "bell") == 0)
91 alloc_action (cop_bell
);
92 else if (strcmp (str
, "echo") == 0)
93 alloc_action (cop_echo
);
94 else if (strncmp (str
, "echo=", 5) == 0)
96 act
= alloc_action (cop_echo
);
97 act
->v
.command
= copy_string_unquote (str
+ 5);
99 else if (strncmp (str
, "exec=", 5) == 0)
101 act
= alloc_action (cop_exec
);
102 act
->v
.command
= copy_string_unquote (str
+ 5);
104 else if (strncmp (str
, "ttyout=", 7) == 0)
106 act
= alloc_action (cop_ttyout
);
107 act
->v
.command
= copy_string_unquote (str
+ 7);
109 else if (strncmp (str
, "sleep=", 6) == 0)
112 time_t n
= strtoul (str
+6, &p
, 10);
114 FATAL_ERROR ((0, 0, _("%s: not a valid timeout"), str
));
115 act
= alloc_action (cop_sleep
);
118 else if (strcmp (str
, "totals") == 0)
119 alloc_action (cop_totals
);
121 FATAL_ERROR ((0, 0, _("%s: unknown checkpoint action"), str
));
125 checkpoint_finish_compile (void)
127 if (checkpoint_option
)
129 if (!checkpoint_action
)
130 /* Provide a historical default */
131 checkpoint_compile_action ("echo");
133 else if (checkpoint_action
)
134 /* Otherwise, set default checkpoint rate */
135 checkpoint_option
= DEFAULT_CHECKPOINT
;
138 static const char *checkpoint_total_format
[] = {
149 ws
.ws_col
= ws
.ws_row
= 0;
150 if ((ioctl (fileno (fp
), TIOCGWINSZ
, (char *) &ws
) < 0) || ws
.ws_col
== 0)
152 const char *col
= getenv ("COLUMNS");
154 return strtol (col
, NULL
, 10);
162 getarg (const char *input
, const char ** endp
, char **argbuf
, size_t *arglen
)
166 char *p
= strchr (input
+ 1, '}');
169 size_t n
= p
- input
;
173 *argbuf
= xrealloc (*argbuf
, *arglen
);
176 memcpy (*argbuf
, input
+ 1, n
);
187 static int tty_cleanup
;
189 static const char *def_format
=
190 "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r";
193 format_checkpoint_string (FILE *fp
, size_t len
,
194 const char *input
, bool do_write
,
197 const char *opstr
= do_write
? gettext ("write") : gettext ("read");
198 char uintbuf
[UINTMAX_STRSIZE_BOUND
];
199 char *cps
= STRINGIFY_BIGINT (cpn
, uintbuf
);
202 static char *argbuf
= NULL
;
203 static size_t arglen
= 0;
209 /* TRANSLATORS: This is a "checkpoint of write operation",
210 *not* "Writing a checkpoint".
211 E.g. in Spanish "Punto de comprobaci@'on de escritura",
212 *not* "Escribiendo un punto de comprobaci@'on" */
213 input
= gettext ("Write checkpoint %u");
215 /* TRANSLATORS: This is a "checkpoint of read operation",
216 *not* "Reading a checkpoint".
217 E.g. in Spanish "Punto de comprobaci@'on de lectura",
218 *not* "Leyendo un punto de comprobaci@'on" */
219 input
= gettext ("Read checkpoint %u");
222 for (ip
= input
; *ip
; ip
++)
228 arg
= getarg (ip
, &ip
, &argbuf
, &arglen
);
240 len
+= format_checkpoint_string (fp
, len
, def_format
, do_write
,
251 len
+= strlen (opstr
);
255 len
+= fprintf (fp
, "%.0f", compute_duration ());
260 const char **fmt
= checkpoint_total_format
, *fmtbuf
[3];
267 if (wordsplit (arg
, &ws
, WRDSF_NOVAR
| WRDSF_NOCMD
|
268 WRDSF_QUOTE
| WRDSF_DELIM
))
269 ERROR ((0, 0, _("cannot split string '%s': %s"),
270 arg
, wordsplit_strerror (&ws
)));
275 for (i
= 0; i
< ws
.ws_wordc
; i
++)
276 fmtbuf
[i
] = ws
.ws_wordv
[i
];
282 len
+= format_total_stats (fp
, fmt
, ',', 0);
284 wordsplit_free (&ws
);
292 const char *fmt
= arg
? arg
: "%c";
294 gettimeofday (&tv
, NULL
);
295 tm
= localtime (&tv
.tv_sec
);
296 len
+= fprintftime (fp
, fmt
, tm
, 0, tv
.tv_usec
* 1000);
302 int w
= arg
? strtoul (arg
, NULL
, 10) : getwidth (fp
);
303 for (; w
> len
; len
++)
332 static FILE *tty
= NULL
;
335 run_checkpoint_actions (bool do_write
)
337 struct checkpoint_action
*p
;
339 for (p
= checkpoint_action
; p
; p
= p
->next
)
350 tty
= fopen ("/dev/tty", "w");
360 int n
= fprintf (stderr
, "%s: ", program_name
);
361 format_checkpoint_string (stderr
, n
, p
->v
.command
, do_write
,
363 fputc ('\n', stderr
);
369 tty
= fopen ("/dev/tty", "w");
371 format_checkpoint_string (tty
, 0, p
->v
.command
, do_write
,
380 sys_exec_checkpoint_script (p
->v
.command
,
381 archive_name_cursor
[0],
387 print_total_stats ();
393 checkpoint_flush_actions (void)
395 struct checkpoint_action
*p
;
397 for (p
= checkpoint_action
; p
; p
= p
->next
)
402 if (tty
&& tty_cleanup
)
404 int w
= getwidth (tty
);
418 checkpoint_run (bool do_write
)
420 if (checkpoint_option
&& !(++checkpoint
% checkpoint_option
))
421 run_checkpoint_actions (do_write
);
425 checkpoint_finish (void)
427 if (checkpoint_option
)
429 checkpoint_flush_actions ();
This page took 0.060922 seconds and 5 git commands to generate.