dvbv5-scan: handle SIGTERM/SIGINT nicely
authorMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 27 Nov 2013 16:36:05 +0000 (14:36 -0200)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 27 Nov 2013 16:54:16 +0000 (14:54 -0200)
Instead of just dying whenever a signal arrives, finish what it was
done. This way, already scanned channels will be written at the file.

At the worse case, after receiving a SIGTERM/SIGINT, it will die after
5 seconds, or after receiving a second SIGTERM/SIGINT.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
lib/libdvbv5/dvb-scan.c
utils/dvb/dvbv5-scan.c

index 2eb8fd1..4a6f225 100644 (file)
@@ -344,6 +344,8 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms,
                              DVB_TABLE_PAT, DVB_TABLE_PAT_PID,
                              (uint8_t **) &dvb_scan_handler->pat,
                              pat_pmt_time * timeout_multiply);
+       if (parms->abort)
+               return dvb_scan_handler;
        if (rc < 0) {
                dvb_logerr("error while waiting for PAT table");
                dvb_scan_free_handler_table(dvb_scan_handler);
@@ -358,6 +360,8 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms,
                                      atsc_filter, DVB_TABLE_VCT_PID,
                                      (uint8_t **)&dvb_scan_handler->vct,
                                      vct_time * timeout_multiply);
+               if (parms->abort)
+                       return dvb_scan_handler;
                if (rc < 0)
                        dvb_logerr("error while waiting for VCT table");
                else if (parms->verbose)
@@ -383,6 +387,10 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms,
                                      DVB_TABLE_PMT, program->pid,
                                      (uint8_t **)&dvb_scan_handler->program[num_pmt].pmt,
                                      pat_pmt_time * timeout_multiply);
+               if (parms->abort) {
+                       dvb_scan_handler->num_program = num_pmt + 1;
+                       return dvb_scan_handler;
+               }
                if (rc < 0) {
                        dvb_logerr("error while reading the PMT table for service 0x%04x",
                                   program->service_id);
@@ -400,6 +408,8 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms,
                              DVB_TABLE_NIT, DVB_TABLE_NIT_PID,
                              (uint8_t **)&dvb_scan_handler->nit,
                              nit_time * timeout_multiply);
+       if (parms->abort)
+               return dvb_scan_handler;
        if (rc < 0)
                dvb_logerr("error while reading the NIT table");
        else if (parms->verbose)
@@ -411,6 +421,8 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms,
                                DVB_TABLE_SDT, DVB_TABLE_SDT_PID,
                                (uint8_t **)&dvb_scan_handler->sdt,
                                sdt_time * timeout_multiply);
+               if (parms->abort)
+                       return dvb_scan_handler;
                if (rc < 0)
                        dvb_logerr("error while reading the SDT table");
                else if (parms->verbose)
@@ -425,6 +437,8 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms,
                                      DVB_TABLE_NIT2, DVB_TABLE_NIT_PID,
                                      (uint8_t **)&dvb_scan_handler->nit,
                                      nit_time * timeout_multiply);
+               if (parms->abort)
+                       return dvb_scan_handler;
                if (rc < 0)
                        dvb_logerr("error while reading the NIT table");
                else if (parms->verbose)
@@ -434,6 +448,8 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms,
                                DVB_TABLE_SDT2, DVB_TABLE_SDT_PID,
                                (uint8_t **)&dvb_scan_handler->sdt,
                                sdt_time * timeout_multiply);
+               if (parms->abort)
+                       return dvb_scan_handler;
                if (rc < 0)
                        dvb_logerr("error while reading the SDT table");
                else if (parms->verbose)
index 87f0b4f..4640e5c 100644 (file)
@@ -172,6 +172,8 @@ static int check_frontend(void *__args,
 
        args->n_status_lines = 0;
        for (i = 0; i < args->timeout_multiply * 40; i++) {
+               if (parms->abort)
+                       return 0;
                rc = dvb_fe_get_stats(parms);
                if (rc)
                        PERROR("dvb_fe_get_stats failed");
@@ -264,6 +266,10 @@ static int run_scan(struct arguments *args,
                                                        args->other_nit,
                                                        args->timeout_multiply);
 
+               if (parms->abort) {
+                       dvb_scan_free_handler_table(dvb_scan_handler);
+                       break;
+               }
                if (!dvb_scan_handler)
                        continue;
 
@@ -363,10 +369,26 @@ static error_t parse_opt(int k, char *optarg, struct argp_state *state)
        return 0;
 }
 
+static int *timeout_flag;
+
+static void do_timeout(int x)
+{
+       (void)x;
+       if (*timeout_flag == 0) {
+               *timeout_flag = 1;
+               alarm(5);
+               signal(SIGALRM, do_timeout);
+       } else {
+               /* something has gone wrong ... exit */
+               exit(1);
+       }
+}
+
+
 int main(int argc, char **argv)
 {
        struct arguments args;
-       int lnb = -1,idx = -1;
+       int err, lnb = -1,idx = -1;
        const struct argp argp = {
                .options = options,
                .parser = parse_opt,
@@ -438,15 +460,14 @@ int main(int argc, char **argv)
        parms->diseqc_wait = args.diseqc_wait;
        parms->freq_bpf = args.freq_bpf;
 
-       if (run_scan(&args, parms)) {
-               dvb_fe_close(parms);
-               free(args.demux_dev);
-               return -1;
-       }
+       timeout_flag = &parms->abort;
+       signal(SIGTERM, do_timeout);
+       signal(SIGINT, do_timeout);
 
-       dvb_fe_close(parms);
+       err = run_scan(&args, parms);
 
+       dvb_fe_close(parms);
        free(args.demux_dev);
 
-       return 0;
+       return err;
 }