⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 linux下获取一些环境信息的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
      sizeof(gnu_table_struct), compare_gnu_table_structs  );  if(!found) return "Unknown gnu long option.";  goto *(found->jump);    /* See gcc extension info.  :-)   */  case_Group:    trace("--Group\n");    arg = grab_gnu_arg();    if(!arg) return "List of real groups must follow --Group.";    err=parse_list(arg, parse_gid);    if(err) return err;    selection_list->typecode = SEL_RGID;    return NULL;  case_User:    trace("--User\n");    arg = grab_gnu_arg();    if(!arg) return "List of real users must follow --User.";    err=parse_list(arg, parse_uid);    if(err) return err;    selection_list->typecode = SEL_RUID;    return NULL;  case_cols:  case_width:  case_columns:    trace("--cols\n");    arg = grab_gnu_arg();    if(arg && *arg){      long t;      char *endptr;      t = strtol(arg, &endptr, 0);      if(!*endptr && (t>0) && (t<2000000000)){        screen_cols = (int)t;        return NULL;      }    }    return "Number of columns must follow --cols, --width, or --columns.";  case_cumulative:    trace("--cumulative\n");    if(s[sl]) return "Option --cumulative does not take an argument.";    include_dead_children = 1;    return NULL;  case_deselect:    trace("--deselect\n");    if(s[sl]) return "Option --deselect does not take an argument.";    negate_selection = 1;    return NULL;  case_no_header:  case_no_headers:  case_no_heading:  case_no_headings:  case_noheader:  case_noheaders:  case_noheading:  case_noheadings:    trace("--noheaders\n");    if(s[sl]) return "Option --no-heading does not take an argument.";    if(header_type) return "Only one heading option may be specified.";    header_type = HEAD_NONE;    return NULL;  case_header:  case_headers:  case_heading:  case_headings:    trace("--headers\n");    if(s[sl]) return "Option --heading does not take an argument.";    if(header_type) return "Only one heading option may be specified.";    header_type = HEAD_MULTI;    return NULL;  case_forest:    trace("--forest\n");    if(s[sl]) return "Option --forest does not take an argument.";    forest_type = 'g';    return NULL;  case_format:    trace("--format\n");    arg=grab_gnu_arg();    if(!arg) return "Format specification must follow --format.";    defer_sf_option(arg, SF_G_format);    return NULL;  case_group:    trace("--group\n");    arg = grab_gnu_arg();    if(!arg) return "List of effective groups must follow --group.";    err=parse_list(arg, parse_gid);    if(err) return err;    selection_list->typecode = SEL_EGID;    return NULL;  case_help:    trace("--help\n");    exclusive("--help");    fwrite(help_message,1,strlen(help_message),stdout);    exit(0);    return NULL;  case_info:    trace("--info\n");    exclusive("--info");    self_info();    exit(0);    return NULL;  case_pid:    trace("--pid\n");    arg = grab_gnu_arg();    if(!arg) return "List of process IDs must follow --pid.";    err=parse_list(arg, parse_pid);    if(err) return err;    selection_list->typecode = SEL_PID;    return NULL;  case_ppid:    trace("--ppid\n");    arg = grab_gnu_arg();    if(!arg) return "List of process IDs must follow --ppid.";    err=parse_list(arg, parse_pid);    if(err) return err;    selection_list->typecode = SEL_PPID;    return NULL;  case_rows:  case_lines:    trace("--rows\n");    arg = grab_gnu_arg();    if(arg && *arg){      long t;      char *endptr;      t = strtol(arg, &endptr, 0);      if(!*endptr && (t>0) && (t<2000000000)){        screen_rows = (int)t;        return NULL;      }    }    return "Number of rows must follow --rows or --lines.";  case_sid:    trace("--sid\n");    arg = grab_gnu_arg();    if(!arg) return "Some sid thing(s) must follow --sid.";    err=parse_list(arg, parse_pid);    if(err) return err;    selection_list->typecode = SEL_SESS;    return NULL;  case_sort:    trace("--sort\n");    arg=grab_gnu_arg();    if(!arg) return "Long sort specification must follow --sort.";    defer_sf_option(arg, SF_G_sort);    return NULL;  case_tty:    trace("--tty\n");    arg = grab_gnu_arg();    if(!arg) return "List of ttys must follow --tty.";    err=parse_list(arg, parse_tty);    if(err) return err;    selection_list->typecode = SEL_TTY;    return NULL;  case_user:    trace("--user\n");    arg = grab_gnu_arg();    if(!arg) return "List of effective users must follow --user.";    err=parse_list(arg, parse_uid);    if(err) return err;    selection_list->typecode = SEL_EUID;    return NULL;  case_version:    trace("--version\n");    exclusive("--version");    display_version();    exit(0);    return NULL;  case_context:    trace("--context\n");    format_flags |= FF_Fc;    return NULL;}/*************** process trailing PIDs  **********************/static const char *parse_trailing_pids(void){  selection_node *pidnode;  /* pid */  selection_node *grpnode;  /* process group */  selection_node *sidnode;  /* session */  char **argp;     /* pointer to pointer to text of PID */  const char *err;       /* error code that could or did happen */  int i;  i = ps_argc - thisarg;  /* how many trailing PIDs, SIDs, PGRPs?? */  argp = ps_argv + thisarg;  thisarg = ps_argc - 1;   /* we must be at the end now */  pidnode = malloc(sizeof(selection_node));  pidnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */  pidnode->n = 0;  grpnode = malloc(sizeof(selection_node));  grpnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */  grpnode->n = 0;  sidnode = malloc(sizeof(selection_node));  sidnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */  sidnode->n = 0;  while(i--){    char *data;    data = *(argp++);    switch(*data){    default:   err = parse_pid(  data, pidnode->u + pidnode->n++); break;    case '-':  err = parse_pid(++data, grpnode->u + grpnode->n++); break;    case '+':  err = parse_pid(++data, sidnode->u + sidnode->n++); break;    }    if(err) return err;     /* the node gets freed with the list */  }  if(pidnode->n){    pidnode->next = selection_list;    selection_list = pidnode;    selection_list->typecode = SEL_PID;  }  /* else free both parts */  if(grpnode->n){    grpnode->next = selection_list;    selection_list = grpnode;    selection_list->typecode = SEL_PGRP;  }  /* else free both parts */  if(sidnode->n){    sidnode->next = selection_list;    selection_list = sidnode;    selection_list->typecode = SEL_SESS;  }  /* else free both parts */  return NULL;}/************** misc stuff ***********/static void reset_parser(void){  w_count = 0;}static int arg_type(const char *str){  int tmp = str[0];  if((tmp>='a') && (tmp<='z'))   return ARG_BSD;  if((tmp>='A') && (tmp<='Z'))   return ARG_BSD;  if((tmp>='0') && (tmp<='9'))   return ARG_PID;  if(tmp=='+')                   return ARG_SESS;  if(tmp!='-')                   return ARG_FAIL;  tmp = str[1];  if((tmp>='a') && (tmp<='z'))   return ARG_SYSV;  if((tmp>='A') && (tmp<='Z'))   return ARG_SYSV;  if((tmp>='0') && (tmp<='9'))   return ARG_PGRP;  if(tmp!='-')                   return ARG_FAIL;  tmp = str[2];  if((tmp>='a') && (tmp<='z'))   return ARG_GNU;  if((tmp>='A') && (tmp<='Z'))   return ARG_GNU;  if(tmp=='\0')                  return ARG_END;                                 return ARG_FAIL;}/* First assume sysv, because that is the POSIX and Unix98 standard. */static const char *parse_all_options(void){  const char *err = NULL;  int at;  while(++thisarg < ps_argc){  trace("parse_all_options calling arg_type for \"%s\"\n", ps_argv[thisarg]);    at = arg_type(ps_argv[thisarg]);    trace("ps_argv[thisarg] is %s\n", ps_argv[thisarg]);    if(at != ARG_SYSV) not_pure_unix = 1;    switch(at){    case ARG_GNU:      err = parse_gnu_option();      break;    case ARG_SYSV:      if(!force_bsd){   /* else go past case ARG_BSD */        err = parse_sysv_option();        break;    case ARG_BSD:        if(force_bsd && !(personality & PER_FORCE_BSD)) return "way bad";      }      prefer_bsd_defaults = 1;      err = parse_bsd_option();      break;    case ARG_PGRP:    case ARG_SESS:    case ARG_PID:      prefer_bsd_defaults = 1;      err = parse_trailing_pids();      break;    case ARG_END:    case ARG_FAIL:      trace("              FAIL/END on [%s]\n",ps_argv[thisarg]);      return "Garbage option.";      break;    default:      printf("                  ?    %s\n",ps_argv[thisarg]);      return "Something broke.";    } /* switch */    if(err) return err;  } /* while */  return NULL;}static void choose_dimensions(void){  if(w_count && (screen_cols<132)) screen_cols=132;  if(w_count>1) screen_cols=OUTBUF_SIZE;  /* perhaps --html and --null should set unlimited width */}static const char *thread_option_check(void){  if(!thread_flags){    thread_flags = TF_show_proc;    return NULL;  }  if(forest_type){    return "Thread display conflicts with forest display.";  }  //thread_flags |= TF_no_forest;  if((thread_flags&TF_B_H) && (thread_flags&(TF_B_m|TF_U_m)))    return "Thread flags conflict; can't use H with m or -m.";  if((thread_flags&TF_B_m) && (thread_flags&TF_U_m))    return "Thread flags conflict; can't use both m and -m.";  if((thread_flags&TF_U_L) && (thread_flags&TF_U_T))    return "Thread flags conflict; can't use both -L and -T.";  if(thread_flags&TF_B_H) thread_flags |= (TF_show_proc|TF_loose_tasks);  if(thread_flags&(TF_B_m|TF_U_m)) thread_flags |= (TF_show_proc|TF_show_task|TF_show_both);  if(thread_flags&(TF_U_T|TF_U_L)){    if(thread_flags&(TF_B_m|TF_U_m|TF_B_H)){      // Got a thread style, so format modification is a requirement?      // Maybe -T/-L has H thread style though. (sorting interaction?)      //return "Huh? Tell procps-feedback@lists.sf.net what you expected.";      thread_flags |= TF_must_use;    }else{      // using -L/-T thread style, so format from elsewhere is OK      thread_flags |= TF_show_task;  // or like the H option?      //thread_flags |= TF_no_sort;    }  }  return NULL;}int arg_parse(int argc, char *argv[]){  const char *err = NULL;  const char *err2 = NULL;  ps_argc = argc;  ps_argv = argv;  thisarg = 0;  if(personality & PER_FORCE_BSD) goto try_bsd;  err = parse_all_options();  if(err) goto try_bsd;  err = thread_option_check();  if(err) goto try_bsd;  err = process_sf_options(!not_pure_unix);  if(err) goto try_bsd;  err = select_bits_setup();  if(err) goto try_bsd;  choose_dimensions();  return 0;try_bsd:  trace("--------- now try BSD ------\n");  reset_global();  reset_parser();  reset_sortformat();  format_flags = 0;  ps_argc = argc;  ps_argv = argv;  thisarg = 0;  /* no need to reset flagptr */  not_pure_unix=1;  force_bsd=1;  prefer_bsd_defaults=1;  if(!( (PER_OLD_m|PER_BSD_m) & personality )) /* if default m setting... */    personality |= PER_OLD_m; /* Prefer old Linux over true BSD. */  /* Do not set PER_FORCE_BSD! It is tested below. */  err2 = parse_all_options();  if(err2) goto total_failure;  err2 = thread_option_check();  if(err2) goto total_failure;  err2 = process_sf_options(!not_pure_unix);  if(err2) goto total_failure;  err2 = select_bits_setup();  if(err2) goto total_failure;  // Feel a need to patch this out? First of all, read the FAQ.  // Second of all, talk to me. Without this warning, people can  // get seriously confused. Ask yourself if users would freak out  // about "ps -aux" suddenly changing behavior if a user "x" were  // added to the system.  //  // Also, a "-x" option is coming. It's already there in fact,  // for some non-default personalities. So "ps -ax" will parse  // as SysV options... and you're screwed if you've been patching  // out the friendly warning. Cut-over is likely to be in 2005.  if(!(personality & PER_FORCE_BSD))    fprintf(stderr, "Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html\n");  // Remember: contact albert@users.sf.net or procps-feedback@lists.sf.net  // if you should feel tempted. Be damn sure you understand all  // the issues. The same goes for other stuff too, BTW. Please ask.  // I'm happy to justify various implementation choices.  choose_dimensions();  return 0;total_failure:  reset_parser();  if(personality & PER_FORCE_BSD) fprintf(stderr, "ERROR: %s\n", err2);  else fprintf(stderr, "ERROR: %s\n", err);  fwrite(help_message,1,strlen(help_message),stderr);  exit(1);  /* return 1; */ /* useless */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -