Skip to content

Instantly share code, notes, and snippets.

@RKX1209
Created November 5, 2017 06:17
Show Gist options
  • Save RKX1209/da92488a20cf4bee0b7ae200e4d02873 to your computer and use it in GitHub Desktop.
Save RKX1209/da92488a20cf4bee0b7ae200e4d02873 to your computer and use it in GitHub Desktop.
dd command source code internal

ddコマンドソースコード・リーディング

(dd.c)

|c| int main (int argc, char **argv) { int i; int exit_status; off_t offset;

install_signal_handlers ();

initialize_main (&argc, &argv); set_program_name (argv[0]); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE);

/* Arrange to close stdout if parse_long_options exits. */ atexit (maybe_close_stdout);

page_size = getpagesize ();

parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, Version, usage, AUTHORS, (char const *) NULL); close_stdout_required = false;

if (getopt_long (argc, argv, "", NULL, NULL) != -1) usage (EXIT_FAILURE);

/* Initialize translation table to identity translation. */ for (i = 0; i < 256; i++) trans_table[i] = i;

/* Decode arguments. / scanargs (argc, argv); [] ... if (input_file == NULL) { input_file = _("standard input"); [] set_fd_flags (STDIN_FILENO, input_flags, input_file); } ... if (output_file == NULL) { output_file = _("standard output"); [] set_fd_flags (STDOUT_FILENO, output_flags, output_file); } else { /* Open the output file with read access only if we might need to read to satisfy a 'seek=' request. If we can't read the file, go ahead with write-only access; it might work. / if ((! seek_records || fd_reopen (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0) && (fd_reopen (STDOUT_FILENO, output_file, O_WRONLY | opts, perms) [] < 0)) error (EXIT_FAILURE, errno, _("failed to open %s"), quote (output_file));
if (seek_records != 0 && !(conversions_mask & C_NOTRUNC)) { uintmax_t size = seek_records * output_blocksize + seek_bytes; if (ftruncate (STDOUT_FILENO, size) != 0) [] { ... } } } } exit_status = dd_copy (); [] ||< []で指定されたオプションの解析を行います。 [],[]では入出力ファイルがオプションで指定されていない場合、標準入出力に切り替えています。 もし出力ファイルが指定されていてかつ-seekが指定されている場合、出力ファイルを一旦[]でread onlyで開いた後、[]でftruncateを実行してseekされた分ファイルのサイズ変更している。 []のdd_copyがファイルコンバートのメイン処理である。

(dd.c)

|c| static int dd_copy (void) { alloc_ibuf (); alloc_obuf (); while (1) { ... if (translation_needed) translate_buffer (ibuf, n_bytes_read); [*]

  if (conversions_mask & C_SWAB)
    bufstart = swab_buffer (ibuf, &n_bytes_read); [*]
  else
    bufstart = ibuf;

  if (conversions_mask & C_BLOCK)
    copy_with_block (bufstart, n_bytes_read); [*]
  else if (conversions_mask & C_UNBLOCK)
    copy_with_unblock (bufstart, n_bytes_read); [*]
  else
    copy_simple (bufstart, n_bytes_read); [*]

} /* If we have a char left as a result of conv=swab, output it. / if (char_is_saved) [] { if (conversions_mask & C_BLOCK) copy_with_block (&saved_char, 1); else if (conversions_mask & C_UNBLOCK) copy_with_unblock (&saved_char, 1); else output_char (saved_char); } ||< [],[],[],[]ではそれぞれconvオプションに(ascii|ebcdic,ibm)変換、swab,block,unblockを指定した場合に、中間bufをそれぞれ変換してobufに出力する処理である。 []は何も指定されていない場合にそのままobufに出力する。 また[]のsaved_charはswabによって奇数文字数の文字を処理した際の一番最後のまだ書き出されていない1文字を格納している。(奇数でこの処理をするのはGNU dd独自らしい)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment