We support short command 'rec*' for 'record' and 'rep*' for 'report' in
lots of sub-commands, but the matching is not quite strict currnetly.
It may be puzzling sometime, like we mis-type a 'recport' to report but
it will perform 'record' in fact without any message.
To fix this, add a check to ensure that the short cmd is valid prefix
of the real command.
Committer testing:
  [root@quaco ~]# perf c2c re sleep 1
   Usage: perf c2c {record|report}
      -v, --verbose         be more verbose (show counter open errors, etc)
  # perf c2c rec sleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.038 MB perf.data (16 samples) ]
  # perf c2c recport sleep 1
   Usage: perf c2c {record|report}
      -v, --verbose         be more verbose (show counter open errors, etc)
  # perf c2c record sleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.038 MB perf.data (15 samples) ]
  # perf c2c records sleep 1
   Usage: perf c2c {record|report}
      -v, --verbose         be more verbose (show counter open errors, etc)
  #
Signed-off-by: Wei Li <liwei391@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Rui Xiang <rui.xiang@huawei.com>
Link: http://lore.kernel.org/lkml/20220325092032.2956161-1-liwei391@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 #include "../perf.h"
 #include "pmu.h"
 #include "pmu-hybrid.h"
+#include "string2.h"
 
 struct c2c_hists {
        struct hists            hists;
        if (!argc)
                usage_with_options(c2c_usage, c2c_options);
 
-       if (!strncmp(argv[0], "rec", 3)) {
+       if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
                return perf_c2c__record(argc, argv);
-       } else if (!strncmp(argv[0], "rep", 3)) {
+       } else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
                return perf_c2c__report(argc, argv);
        } else {
                usage_with_options(c2c_usage, c2c_options);
 
                        kmem_page = 1;
        }
 
-       if (!strncmp(argv[0], "rec", 3)) {
+       if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
                symbol__init(NULL);
                return __cmd_record(argc, argv);
        }
 
 #include "util/ordered-events.h"
 #include "util/kvm-stat.h"
 #include "ui/ui.h"
+#include "util/string2.h"
 
 #include <sys/prctl.h>
 #ifdef HAVE_TIMERFD_SUPPORT
                goto perf_stat;
        }
 
-       if (!strncmp(argv[1], "rec", 3))
+       if (strlen(argv[1]) > 2 && strstarts("record", argv[1]))
                return kvm_events_record(&kvm, argc - 1, argv + 1);
 
-       if (!strncmp(argv[1], "rep", 3))
+       if (strlen(argv[1]) > 2 && strstarts("report", argv[1]))
                return kvm_events_report(&kvm, argc - 1 , argv + 1);
 
 #ifdef HAVE_TIMERFD_SUPPORT
                }
        }
 
-       if (!strncmp(argv[0], "rec", 3))
+       if (strlen(argv[0]) > 2 && strstarts("record", argv[0]))
                return __cmd_record(file_name, argc, argv);
-       else if (!strncmp(argv[0], "rep", 3))
+       else if (strlen(argv[0]) > 2 && strstarts("report", argv[0]))
                return __cmd_report(file_name, argc, argv);
        else if (!strncmp(argv[0], "diff", 4))
                return cmd_diff(argc, argv);
 
 #include "util/session.h"
 #include "util/tool.h"
 #include "util/data.h"
+#include "util/string2.h"
 
 #include <sys/types.h>
 #include <sys/prctl.h>
        if (!argc)
                usage_with_options(lock_usage, lock_options);
 
-       if (!strncmp(argv[0], "rec", 3)) {
+       if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
                return __cmd_record(argc, argv);
-       } else if (!strncmp(argv[0], "report", 6)) {
+       } else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
                trace_handler = &report_lock_ops;
                if (argc) {
                        argc = parse_options(argc, argv,
 
 #include "util/symbol.h"
 #include "util/pmu.h"
 #include "util/pmu-hybrid.h"
+#include "util/string2.h"
 #include <linux/err.h>
 
 #define MEM_OPERATION_LOAD     0x1
                        mem.input_name = "perf.data";
        }
 
-       if (!strncmp(argv[0], "rec", 3))
+       if (strlen(argv[0]) > 2 && strstarts("record", argv[0]))
                return __cmd_record(argc, argv, &mem);
-       else if (!strncmp(argv[0], "rep", 3))
+       else if (strlen(argv[0]) > 2 && strstarts("report", argv[0]))
                return report_events(argc, argv, &mem);
        else
                usage_with_options(mem_usage, mem_options);
 
        if (!strcmp(argv[0], "script"))
                return cmd_script(argc, argv);
 
-       if (!strncmp(argv[0], "rec", 3)) {
+       if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
                return __cmd_record(argc, argv);
        } else if (!strncmp(argv[0], "lat", 3)) {
                sched.tp_handler = &lat_ops;
                sched.tp_handler = &map_ops;
                setup_sorting(&sched, latency_options, latency_usage);
                return perf_sched__map(&sched);
-       } else if (!strncmp(argv[0], "rep", 3)) {
+       } else if (strlen(argv[0]) > 2 && strstarts("replay", argv[0])) {
                sched.tp_handler = &replay_ops;
                if (argc) {
                        argc = parse_options(argc, argv, replay_options, replay_usage, 0);
 
        if (symbol__validate_sym_arguments())
                return -1;
 
-       if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
+       if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
                rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
                if (!rec_script_path)
                        return cmd_record(argc, argv);
        }
 
-       if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
+       if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
                rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
                if (!rep_script_path) {
                        fprintf(stderr,
 
        } else
                stat_config.csv_sep = DEFAULT_SEPARATOR;
 
-       if (argc && !strncmp(argv[0], "rec", 3)) {
+       if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
                argc = __cmd_record(argc, argv);
                if (argc < 0)
                        return -1;
-       } else if (argc && !strncmp(argv[0], "rep", 3))
+       } else if (argc && strlen(argv[0]) > 2 && strstarts("report", argv[0]))
                return __cmd_report(argc, argv);
 
        interval = stat_config.interval;
 
 #include "util/tool.h"
 #include "util/data.h"
 #include "util/debug.h"
+#include "util/string2.h"
 #include <linux/err.h>
 
 #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE
                return -1;
        }
 
-       if (argc && !strncmp(argv[0], "rec", 3)) {
+       if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
                argc = parse_options(argc, argv, timechart_record_options,
                                     timechart_record_usage,
                                     PARSE_OPT_STOP_AT_NON_OPTION);