2020年10月31日 星期六

busybox options

標準 C 函式庫提供解析指令選項的功能。

引數中,以「-」開頭是選項,接著用一個字元代表不同選項。如果選項有參數,會是下個字元、或者是下個引數。

getopt() 一次檢查一個引數是不是選項,回傳選項字元,和選項的參數 (有的話),並指到下個引數。重複呼叫 getopt(),可以回傳一系列符合的選項字元。

#include <unistd.h>

int getopt(int argc, char * const argv[], const char *optstring);

extern char *optarg;
extern int optind, opterr, optopt;
  • argv 是引數 (指到字串) 的陣列。「--」會強制結束選項掃描。
  • optstring 是合法的選項字元。如果某個選項有參數,其字元會接著「:」。
    • [GNU 擴充] 如果參數是選擇性的,看引數中選項字元有無下個字元,其選項字元會接著「::」。
    • [GNU 擴充] 如果 optstring 包含「W;」,表示 -W foo 視為 long option --foo (GNU 擴充)。
    • 「+」開頭或環境變數 POSIXLY_CORRECT 有設:遇到非選項就停止處理。
    • 「-」開頭,非選項部份則視為 character code 1 的參數,讓 argv[] 維持原本排列。預設 getopt() 會改造 argv[],讓非選項部份排到後面。
    • 開頭 (「+」或「-」之後) 是「:」:錯誤不印 stderr,選項缺參數時改回「:」。
  • 回傳值
    • -1:結束
    • '?':選項不存在或缺參數,預設會印錯誤訊息到 stderr,optopt 放錯誤的選項字元。如果全域變數 opterr 設為 0,則不印 stderr。
    • ':':缺參數
    • 選項字元:搭配全域變數 optarg 回傳選項的參數。
  • 全域變數 optind,getopt() 每次檢查 argv[optind],並回傳下個參數索引 (視選項的參數狀況加 1 或加 2)。

長選項解析

#include <getopt.h>

int getopt_long(int argc, char * const argv[], const char *optstring,
           const struct option *longopts, int *longindex);

int getopt_long_only(int argc, char * const argv[], const char *optstring,
           const struct option *longopts, int *longindex);

getopt_long() 除了 getopt() 功能外也接受格式「--arg=param」或「--arg param」的 long  options。如果只接受 long options,optstring 傳空字串「""」(非 NULL)。long option 名稱可以 abbreviated if the abbreviation is unique or is an exact match for some defined option.

longopts 陣列內容是

struct option {
const char *name; //選項名稱
int         has_arg;//0==沒參數, 1==有參數, 2==選擇性參數
int        *flag; //NULL==回傳 val。其它回傳 0,*flag 設為 val。
int         val; //要回傳的值
};

最後 element 填為 0。如果 longindex 不是 NULL,回傳符合的 longopts[] index。

getopt_long_only()  類似 getopt_long(),但「-」一開始也作為 long option,不符合才比對 short option。

busybox ....

uint32_t getopt32(char **argv, const char *applet_opts, ...)

掃描 argv 字串陣列中「-」開頭的選項,依據 applet_opts 字母的順序回傳 bitmask。字母後面有「:」包表示選項有引數,需要提供指標來存。

離開時,全域變數 optind 設為選項用掉的數目,如此一來 argc -= optind; argv += optind; argc 等於剩下非選項的部份,第一個參數會是 argv[0]。

參考來源:

  1. man 3 getopt
  2. busybox libbb/getopt32.c
  3. bash options

沒有留言:

張貼留言

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...