トップ «前の日記(2014-05-25) 最新 次の日記(2014-05-27)» 編集

ヨタの日々

2001|08|09|10|11|12|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|12|
2024|01|02|03|

2014-05-26 :-(

_ 午前

0530 起床

0700 食堂

0830 出勤 && タッチパネルはかく語りき

_ 午後

1300 タッチパネルはかく語りき

_

1700 残業アワー

2100 退勤

2200 飯。牛丼

_ [NetBSD][/bin/echo][コードリーディング]NetBSD /bin/echo を読む

src/bin/echo/echo.c

こう使ったとする。

% echo foo bar baz
foo bar baz

コード読む

/* ARGSUSED */
int
main(int argc, char *argv[])
{
  int nflag;

  setprogname(argv[0]);
  (void)setlocale(LC_ALL, "");


  // getopt 使うまでもないよ!

  /* This utility may NOT do getopt(3) option parsing. */
  if (*++argv && !strcmp(*argv, "-n")) {
    ++argv;
    nflag = 1;
  }
  else
    nflag = 0;


  // argv は以下のとおり
  //   argv[1] : foo
  //   argv[2] : bar
  //   argv[3] : baz

  while (*argv) {
    (void)printf("%s", *argv);
    if (*++argv)
      (void)putchar(' ');
  }

  // 最後に改行を印字
  if (nflag == 0)
    (void)putchar('\n');
  fflush(stdout);

  // fflush の動作を保証するため?
  if (ferror(stdout))
    exit(1);
  exit(0);
  /* NOTREACHED */
}

-n オプションの意味

echo - NetBSD Manual Pages

    -n    Do not print the trailing newline character.

_ [NetBSD][/bin/hostname][コードリーディング]NetBSD /bin/hostname を読む

ソース src/bin/hostname/hostname.c

マニュアル hostname - NetBSD Manual Pages

使用例

% hostname
sakura.area51.gr.jp
% hostname -s
sakura

コード読む。

main で完結する。

冒頭の変数

  char *p, hostname[MAXHOSTNAMELEN + 1];

MAXHOSTNAMELEN は src/sys/sys/param.h に定義されてる。

/*
 * Machine-independent constants (some used in following include files).
 * Redefined constants are from POSIX 1003.1 limits file.
 *
 * MAXCOMLEN should be >= sizeof(ac_comm) (see <acct.h>)
 * MAXHOSTNAMELEN should be >= (_POSIX_HOST_NAME_MAX + 1) (see <limits.h>)
 * MAXLOGNAME should be >= UT_NAMESIZE (see <utmp.h>)
 */
#include <sys/syslimits.h>

#define	MAXCOMLEN	16		/* max command name remembered */
#define	MAXINTERP	PATH_MAX	/* max interpreter file name length */
/* DEPRECATED: use LOGIN_NAME_MAX instead. */
#define	MAXLOGNAME	(LOGIN_NAME_MAX - 1) /* max login name length */
#define	NCARGS		ARG_MAX		/* max bytes for an exec function */
#define	NGROUPS		NGROUPS_MAX	/* max number groups */
#define	NOGROUP		65535		/* marker for empty group set member */
#define	MAXHOSTNAMELEN	256		/* max hostname size */

おもな処理。ようするに sethostname または gethostname を呼ぶ。

  if (*argv) {

    // ホスト名が指定されている場合はホスト名を設定
    if (sethostname(*argv, strlen(*argv)))
      err(1, "sethostname");
  } else {

    // 指定されてなければ gethostname でホスト名を取得
    if (gethostname(hostname, sizeof(hostname)))
      err(1, "gethostname");

    // ヌル文字を入れる
    hostname[sizeof(hostname) - 1] = '\0';

    // -s で呼び出された場合 最初の . を探す。
    // そこにヌル文字を突っ込むことで強制的に文字列を終了する。つまりドメイン名を削除
    if (sflag && (p = strchr(hostname, '.')))
      *p = '\0';
    (void)printf("%s\n", hostname);
  }

hostname は以下のファイルに定義されている。libc です。

src/lib/libc/gen/gethostname.c

int
gethostname(name, namelen)
  char *name;
  size_t namelen;
{
  int mib[2];
  size_t size;

  _DIAGASSERT(name != NULL);

  mib[0] = CTL_KERN;
  mib[1] = KERN_HOSTNAME;
  size = namelen;

  // 第 3 引数が非 NULL なので情報を取得
  if (sysctl(mib, 2, name, &size, NULL, 0) == -1)
    return (-1);

  return (0);
}

sethostname も同じところにある。

src/lib/libc/gen/sethostname.c

int
sethostname(name, namelen)
  const char *name;
  size_t namelen;
{
  int mib[2];

  _DIAGASSERT(name != NULL);

  mib[0] = CTL_KERN;
  mib[1] = KERN_HOSTNAME;

  // 第 3 引数が NULL なので情報を設定
  if (sysctl(mib, 2, NULL, NULL, name, namelen) == -1)
    return (-1);
  return (0);
}

双方とも sysctl を呼んでいる。

sysctl のマニュアル。

sysctl(3) より。sysctl の第 3 引数が NULL ならば設定。そうでなければ情報を取得。

     The information is copied into the buffer specified by oldp.  The size of
     the buffer is given by the location specified by oldlenp before the call,
     and that location gives the amount of data copied after a successful
     call.  If the amount of data available is greater than the size of the
     buffer supplied, the call supplies as much data as fits in the buffer
     provided and returns with the error code ENOMEM.  If the old value is not
     desired, oldp and oldlenp should be set to NULL.

sysctl(7) より。CTL_KERN と KERN_HOSTNAME を指定すると kern.hostname が使われる。

     Name        Constant        Next level names     Description
     kern        CTL_KERN        <sys/sysctl.h>       High kernel limits
     kern.hostname (KERN_HOSTNAME)
             Get or set the hostname(1).