2009年06月03日 request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 [長年日記]
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1
2, 3日前からlib100の/val/log/syslogに
request_module[net-pf-10]: waitpid(3788,...) failed, errno 1
のメッセージが連続して記録されている。なんやらIPV6関係のモジュールをロードしようとして失敗しているようなのだが、そもそもIPV6での接続などしていないので何故このようなメッセージが出始めたのかは不明。
とりあえず、
$ egrep -i ipv6 /usr/src/linux/.config # CONFIG_IPV6 is not set
の設定にして(IPV6を外して)カーネルを再構築中。
_ firefox-3.0.10 version up
.mozconfig
. $topsrcdir/browser/config/mozconfig ac_add_options --disable-debug ac_add_options --disable-dbus ac_add_options --disable-jemalloc ac_add_options --enable-optimize ac_add_options --enable-default-toolkit=cairo-gtk2
build
nice make -f client.mk build nice make package
2009年06月04日 request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その2) [長年日記]
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その2)
カーネル再構築でもメッセージは消えなかった。その後 /etc/modprobe.conf に
install ipv6 /sbin/modprobe -n -i ipv6
を記述する方法も試したが効果無し。
_ sendmailに関係する?
その後、/var/log/messagesと/var/log/syslogを同時にtail -fで表示させて観察していると、どうやら外部からメールが到着してsendmailにキックがかかると、上記のエラーが発生しているらしいことを発見した。
2009年06月05日 Java儂(わし)的解釈によるメモ [長年日記]
_ Java儂(わし)的解釈によるメモ
COBOLERのおっさんによる、まったく身勝手な解釈によるJavaの小さな小さなサンプル集。とりあえずテキスト処理とネットワークプログラミングが出来ることを目標としてる。
hello.java
// // Hello world // // compile : javac -encoding utf-8 hello.java // run : java -cp . hello // public class hello { public static void main(String[] args) { System.out.println("Hello java world."); } }
クラスの中で定義されているメソッドは、通常そのクラスがnew(生成)されて初めて実体となり、呼び出す事ができるのだが、メッソドであるmain()は自分が属するhelloクラスが誰からもnew(生成)されていないにもかかわらず、呼び出す事ができている。
それは static という宣言に関係している。
staticの無いメソッドや変数の宣言の場合、それらはnew(生成)されたオブジェクトの内部に初めて実体として出現する。それに対して static で宣言されたメソッドや変数はクラスの定義そのものに実体を宿す。
よって、誰からもnew(生成)されなくても、既に存在しているので呼び出す事が可能となっている。
hello.java - 実行結果
Hello java world.
var.java - 変数
// // 「変数」テスト // // compile : javac -encoding utf-8 var.java // run : java -cp . var // public class var { public static void main(String[] args) { // // 変数宣言 // byte wk_byte; short wk_short; int wk_int; long wk_long; float wk_float; double wk_double; char wk_char; // 内部表現はUnicodeとなる char wk_nchar; // 内部表現はUnicodeとなる boolean wk_boolean; String wk_String; // 内部表現はUnicodeとなる // // 変数へ代入 // wk_byte = 10; wk_short = 10; wk_int = 10; wk_long = 10; wk_float = 10.1F; wk_double = 10.1; wk_char = 'A'; wk_nchar = 'あ'; wk_boolean = true; wk_String = "abcdefg"; // // 変数を参照 // System.out.println("wk_byte=" + wk_byte); System.out.println("wk_short=" + wk_short); System.out.println("wk_int=" + wk_int); System.out.println("wk_long=" + wk_long); System.out.println("wk_float=" + wk_float); System.out.println("wk_double=" + wk_double); System.out.println("wk_char=" + wk_char); System.out.println("wk_nchar=" + wk_nchar); System.out.println("wk_boolean=" + wk_boolean); System.out.println("wk_String=" + wk_String); } }
byte から booleanはjavaの言語仕様としてサポートされる基本型。charはUNICODEでデータを保持するので、従来言っていた「半角文字」「全角文字」(この表現自体どうかと思うが、他にうまく言えないので...)の区別無く「一文字」を格納できる。
最後に出てきた Stringは「型」ではなく「クラス」。C言語が文字列を、「言語仕様で直接サポートするchar型」の配列として扱っていたのと似ている。
var.java - 実行結果
wk_byte=10 wk_short=10 wk_int=10 wk_long=10 wk_float=10.1 wk_double=10.1 wk_char=A wk_nchar=あ wk_boolean=true wk_String=abcdefg
var_array.java - 配列
// // 「配列」テスト // // compile : javac -encoding utf-8 var_array.java // run : java -cp . var_array // public class var_array { public static void main(String[] args) { // // 配列の初期化 // int[] wk_int1 = new int[10]; int[] wk_int2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // // 配列への代入 // wk_int1[0] = 0; wk_int1[9] = 9; // // 配列の参照 // System.out.println("wk_int1.length=" + wk_int1.length); System.out.println("wk_int1[0]=" + wk_int1[0]); System.out.println("wk_int1[5]=" + wk_int1[5]); System.out.println("wk_int1[9]=" + wk_int1[9]); System.out.println("wk_int2.length=" + wk_int2.length); System.out.println("wk_int2[0]=" + wk_int2[0]); System.out.println("wk_int2[5]=" + wk_int2[5]); System.out.println("wk_int2[9]=" + wk_int2[9]); } }
var_array.java - 実行結果
wk_int1.length=10 wk_int1[0]=0 wk_int1[5]=0 wk_int1[9]=9 wk_int2.length=10 wk_int2[0]=0 wk_int2[5]=5 wk_int2[9]=9
var_hash.java - ハッシュ
// // 「ハッシュ」テスト // // compile : javac -encoding utf-8 var_hash.java // run : java -cp . var_hash // import java.util.*; public class var_hash { public static void main(String[] args) { // // ハッシュ作成 // HashMap<String, String> map = new HashMap<String, String>(); // // ハッシュに格納 // map.put("apple", "red"); map.put("melon", "green"); map.put("lemon", "yellow"); // // ハッシュを参照 // System.out.println("melon = " + map.get("melon")); System.out.println("apple = " + map.get("apple")); System.out.println("lemon = " + map.get("lemon")); // // キーの数だけ繰り返す // Iterator ite = map.keySet().iterator(); while (ite.hasNext()){ Object s = ite.next(); System.out.println(s.toString() + " = " + map.get(s.toString()) + " by keySet"); } // // キー順ハッシュ作成 // TreeMap<String, String> tmap = new TreeMap<String, String>(map); // // キーの数だけ繰り返す // for (String s : tmap.keySet()){ System.out.println(s + " = " + tmap.get(s) + " by TreeMap+keySet"); } // // キー指定で削除 // map.remove("apple"); for (String s : map.keySet()){ System.out.println(s + " = " + map.get(s) + " by apple removed"); } } }
var_hash.java - 実行結果
melon = green apple = red lemon = yellow melon = green by keySet apple = red by keySet lemon = yellow by keySet apple = red by TreeMap+keySet lemon = yellow by TreeMap+keySet melon = green by TreeMap+keySet melon = green by apple removed lemon = yellow by apple removed
var_linkedlist.java - リンクリスト
// // 「LinkedList」テスト // // compile : javac -encoding utf-8 var_linkedlist.java // run : java -cp . var_linkedlist // import java.util.*; public class var_linkedlist { public static void main(String[] args) { // // リストの初期化 // LinkedList<String> ll = new LinkedList<String>(); // // リストへの代入 // ll.add("文字列1"); ll.add("文字列2"); ll.add("文字列3"); ll.add("文字列4"); ll.add("文字列5"); // // 要素数取得 // System.out.println("size = " + ll.size()); // // 直接参照 // System.out.println("ll.get(2) = " + ll.get(2)); // // 直接置換 // ll.set(2, "置換された文字列3"); // // リストの参照 // Iterator ite = ll.iterator(); while (ite.hasNext()){ System.out.println(ite.next()); } // // リストからの削除 // ll.remove(); // 先頭の削除 ll.remove(2); // 2番目(0オリジンで)の削除 // // リストの参照 // ite = ll.iterator(); while (ite.hasNext()){ System.out.println(ite.next()); } } }
実行結果
size = 5 ll.get(2) = 文字列3 文字列1 文字列2 置換された文字列3 文字列4 文字列5 文字列2 置換された文字列3 文字列5
var_henkan.java - 型変換
// // 「型変換」テスト // // compile : javac -encoding utf-8 var_henkan.java // run : java -cp . var_henkan // public class var_henkan { public static void main(String[] args) { int wk_int; long wk_long; Integer wk_Integer; Long wk_Long; // // 文字列 -> 数値 // wk_int = Integer.valueOf("256"); wk_long = Long.valueOf("256"); System.out.println("wk_int + wk_long = " + (wk_int + wk_long) + " by valueOf"); // // 文字列 -> 数値オブジェクト // wk_Integer = Integer.parseInt("256"); wk_Long = Long.parseLong("256"); System.out.println("wk_Integer + wk_Long = " + (wk_Integer + wk_Long) + " by parse{Int|Long}"); // // 数値 -> 文字列 // String str_int = Integer.toString(256); String str_long = Long.toString(256); System.out.println("str_int + str_long = " + (str_int + str_long) + " by toString"); } }
Float, Doubleに関しても同じような感じでいける ;)
var_henkan.java - 実行結果
wk_int + wk_long = 512 by valueOf wk_Integer + wk_Long = 512 by parse{Int|Long} str_int + str_long = 256256 by toString
string_hikisu.java - 引数
// // 「引数」テスト // // compile : javac -encoding utf-8 string_hikisu.java // run : java -cp . string_hikisu // public class string_hikisu { public static void main(String[] args) { // // 引数の個数 // System.out.println("args.length=" + args.length); // // 引数の参照 // for (int i = 0; i < args.length; i++){ System.out.println("args[" + i + "]=" + args[i]); } } }
string_hikisu.java - 実行結果
$ java string_hikisu aaa bbb args.length=2 args[0]=aaa args[1]=bbb
string_indexOf.java - 文字列位置
// // 「indexOf」テスト // // compile : javac -encoding utf-8 string_indexOf.java // run : java -cp . string_indexOf // public class string_indexOf { public static void main(String[] args) { // // 文字列の位置 // String str = "123456789"; System.out.println("position 567 in " + str + " is " + str.indexOf("567")); } }
string_indexOf.java - 実行結果
position 567 in 123456789 is 4
string_length.java - 文字列長
// // 「length」テスト // // compile : javac -encoding utf-8 string_length.java // run : java -cp . string_length // public class string_length { public static void main(String[] args) { // // 文字列長 // String str = "123456789"; System.out.println("length of " + str + " is " + str.length()); // // 日本語を含む場合の文字列長 // str = "漢字はどうなる?"; System.out.println("length of " + str + " is " + str.length()); } }
string_length.java - 実行結果
length of 123456789 is 9 length of 漢字はどうなる? is 8
string_mojihenkan.java - 文字コード変換
// // 「文字コード変換」テスト // // compile : javac -encoding utf-8 string_mojihenkan.java // run : java -cp . string_mojihenkan // import java.io.*; public class string_mojihenkan { public static void main(String[] args) { String str = "javaのStringはunicodeで表現される\n"; try { // // 文字コードをUNICODE(java内部表現)から変換 // // byte[] bt = str.getBytes("JIS"); // byte[] bt = str.getBytes("SHIFT_JIS"); // byte[] bt = str.getBytes("UTF-8"); byte[] bt = str.getBytes("EUC-JP"); System.out.write(bt); } catch(UnsupportedEncodingException e) { System.out.println("encoding error happened : " + e); } catch(IOException e) { System.out.println("write error happened : " + e); } } }
string_mojihenkan.java - 実行結果
javaのStringはunicodeで表現される
string_replaceAll.java - 正規表現による文字列置換
// // 「replaceAll」テスト // // compile : javac -encoding utf-8 string_replaceAll.java // run : java -cp . string_replaceAll // public class string_replaceAll { public static void main(String[] args) { // // 正規表現で文字列置換 // String str_before = "ABCDEFGHIJKLMN"; String str_after = str_before.replaceAll("B.*M", "B to M"); System.out.println("str_before = " + str_before); System.out.println("str_after = " + str_after); } }
string_replaceAll.java - 実行結果
str_before = ABCDEFGHIJKLMN str_after = AB to MN
string_split.java - 文字列分割
// // 「split」テスト // // compile : javac -encoding utf-8 string_split.java // run : java -cp . string_split // public class string_split { public static void main(String[] args) { // // 文字列分割 // String str = "apple,lemon,,orange,,,lemon"; String[] strArry = str.split(",,*"); for (int i = 0; i < strArry.length; i++){ System.out.println("strArry[" + i + "] = " + strArry[i]); } // // 文字列分割(分割制限有り) // str = "apple,lemon,orange,lemon"; strArry = str.split(",", 3); for (int i = 0; i < strArry.length; i++){ System.out.println("strArry[" + i + "] = " + strArry[i] + " by limited 3"); } } }
string_split.java - 実行結果
strArry[0] = apple strArry[1] = lemon strArry[2] = orange strArry[3] = lemon strArry[0] = apple by limited 3 strArry[1] = lemon by limited 3 strArry[2] = orange,lemon by limited 3
string_scanner.java - 文字列分割
// // 「scanner」テスト // // compile : javac -encoding utf-8 string_scanner.java // run : java -cp . string_scanner // import java.util.*; public class string_scanner { public static void main(String[] args) throws Exception { // // Scanner s = new Scanner(System.in); // こんな感じに、引数にストリームも指定可能 // Scanner s = new Scanner("apple,lemon,,orange,,,lemon"); s.useDelimiter(",,*"); while (s.hasNext()) { System.out.println(s.next()); } } }
string_scanner.java - 実行結果
apple lemon orange lemon
string_substring.java - 文字列部分参照
// // 「substring」テスト // // compile : javac -encoding utf-8 string_substring.java // run : java -cp . string_substring // public class string_substring { public static void main(String[] args) { // // 文字列部分参照(アルファベット) // String str = "123456789"; System.out.println("str = " + str); System.out.println("str.substring(3, 6) = " + str.substring(3, 6)); // // 文字列部分参照(漢字) // str = "あいうえおかきくけこ"; System.out.println("str = " + str); System.out.println("str.substring(3, 6) = " + str.substring(3, 6)); // // 文字列部分参照(アルファベット&漢字混在) // str = "あAいBうCえDお"; System.out.println("str = " + str); System.out.println("str.substring(3, 6) = " + str.substring(3, 6)); } }
string_substring.java - 実行結果
str = 123456789 str.substring(3, 6) = 456 str = あいうえおかきくけこ str.substring(3, 6) = えおか str = あAいBうCえDお str.substring(3, 6) = BうC
if_test.java - 条件分岐
// // 「if」テスト // // compile : javac -encoding utf-8 if_test.java // run : java -cp . if_test // import java.util.regex.*; public class if_test { public static void main(String[] args) { int i = 10; // // 数値比較 // if (i > 0){ System.out.println(i + " is plus"); }else if (i == 0){ System.out.println(i + " is zero"); }else{ System.out.println(i + " is minus"); } // // 文字列比較 // String s = "ABCDE"; if (s.compareTo("BCDEF") > 0){ System.out.println(s + " > BCDEF"); }else if (s.compareTo("BCDEF") == 0){ System.out.println(s + " = BCDEF"); }else{ System.out.println(s + " < BCDEF"); } // // 文字列比較(その他) // // if (s.equals("BCDEF")){ // 等しい時の処理 // }else{ // 等しくない時の処理 // } // // // 正規表現比較 // Pattern pattern = Pattern.compile("^A.*E$"); Matcher matcher = pattern.matcher(s); // // if (matcher.find()){ // 部分比較 // if (matcher.matches()){ // 全領域比較 System.out.println(s + " matches to /^A.*E$/"); }else{ System.out.println(s + " not matches to /^A.*E$/"); } // // if (s.matches("^A.*E$)){ // 実は、Stringクラスにも matchesメソッはありました... // } // } }
if_test.java - 実行結果
10 is plus ABCDE < BCDEF ABCDE matches to /^A.*E$/
switch_test.java - 条件多分岐
// // 「switch」テスト // // compile : javac -encoding utf-8 switch_test.java // run : java -cp . switch_test // import java.util.regex.*; public class switch_test { public static void main(String[] args) { int i = 10; switch (i){ case 1: System.out.println(i + " is 1"); break; case 10: System.out.println(i + " is 10"); break; default: System.out.println(i + " is not 1 and 10"); break; } } }
switch_test.java - 実行結果
10 is 10
while_test.java - 繰り返し
// // 「while」テスト // // compile : javac -encoding utf-8 while_test.java // run : java -cp . while_test // public class while_test { public static void main(String[] args) { // // while(条件有り) // int i = 0; while (i < 10){ System.out.println("i = " + i); i++; } // // while(永久ループ & breakによる中断) // i = 0; while (true){ System.out.println("i = " + i + " terminated by break"); if (i > 10){ break; } i++; } } }
while_test.java - 実行結果
i = 0 i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9 i = 0 terminated by break i = 1 terminated by break i = 2 terminated by break i = 3 terminated by break i = 4 terminated by break i = 5 terminated by break i = 6 terminated by break i = 7 terminated by break i = 8 terminated by break i = 9 terminated by break i = 10 terminated by break i = 11 terminated by break
for_test.java - 繰り返し(2)
// // 「for」テスト // // compile : javac -encoding utf-8 for_test.java // run : java -cp . for_test // import java.util.*; public class for_test { public static void main(String[] args) { // // for文 // for (int i = 0; i < 10; i++){ System.out.println("i =" + i); } // // for文(配列分だけ繰り返す) // String[] arry = {"apple", "melon", "lemon"}; for (String thing: arry){ System.out.println("thing =" + thing); } // // for文(ハッシュのキー分だけ繰り返す) // HashMap<String, String> map = new HashMap<String, String>(); map.put("apple", "red"); map.put("melon", "green"); map.put("lemon", "yellow"); for (String s : map.keySet()){ System.out.println(s + " = " + map.get(s)); } } }
for_test.java - 実行結果
i =0 i =1 i =2 i =3 i =4 i =5 i =6 i =7 i =8 i =9 thing =apple thing =melon thing =lemon melon = green apple = red lemon = yellow
function_test.java - 関数
// // 「function」テスト // // compile : javac -encoding utf-8 function_test.java // run : java -cp . function_test // public class function_test { public static void main(String[] args) { function_test main = new function_test(); String str = main.my_func("arg1", "arg2"); System.out.println(str); function_test_my_class mc = new function_test_my_class(); str = mc.my_func2("ARG1", "ARG2"); System.out.println(str); } // // 同一クラス内のファンクション // String my_func(String arg1, String arg2){ return arg1 + " and " + arg2; } } class function_test_my_class { // // 同一クラス外のファンクション // String my_func2(String arg1, String arg2){ return arg1 + " and " + arg2; } }
ちよっと奇妙に思うかもしれないが、mainメソッドの中で自分の属するクラス(function_test)をnew(生成)している。一見無限ループを起こすかのように思うかもしれないが問題ない。
staticなメソッド、変数を含むクラスをnew(生成)した場合は、staticなもの以外が動的に生成されるだけなので、mainメソッドがいくつも出来てループ状態になる...という事は無い。
上記の場合、newすることで生成された main オブジェクトを介して mainメソッドは自分の属するクラスの(staticでない)メソッドや変数にアクセスできるようになる。
また、mainメソッドを含むクラスをnew(生成)しなかった場合はどうかというと、mainメソッドは自分の属するクラスのメソッドや変数であっても、static宣言されたものしかアクセスできない。なぜならnew(生成)されない限りそれらは存在しないから。
function_test.java - 実行結果
arg1 and arg2 ARG1 and ARG2
getenv_test.java - 環境変数取得
// // 「getenv」テスト // // compile : javac -encoding utf-8 getenv_test.java // run : java -cp . getenv_test // public class getenv_test { public static void main(String[] args) { // // 環境変数 PATH 取得 // System.out.println(System.getenv("LC_ALL")); } }
getenv_test.java - 実行結果
ja_JP.eucJP
get_datetime.java - 日付、時刻の取得
// // 「日時取得」テスト // // compile : javac -encoding utf-8 get_datetime.java // run : java -cp . get_datetime // import java.util.Calendar; public class get_datetime { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); int year = cal.get(cal.YEAR); int month = cal.get(cal.MONTH) + 1; int day = cal.get(cal.DATE); int hour = cal.get(cal.HOUR_OF_DAY); int minute = cal.get(cal.MINUTE); int second = cal.get(cal.SECOND); int millisecond = cal.get(cal.MILLISECOND); System.out.printf("%04d/%02d/%02d %02d:%02d:%02d.%03d\n", year, month, day, hour, minute, second, millisecond); } }
get_datetime.java - 実行結果
2009/06/05 22:26:47.095
exec_program.java - OSコマンド実行(バックグラウンドで実行し、親子で通信あり)
// // 「外部コマンド実行」テスト // // compile : javac -encoding utf-8 exec_program.java // run : java -cp . exec_program // import java.io.*; public class exec_program { public static void main(String[] args) { try { // // 実行 // Process process = Runtime.getRuntime().exec("ls -al *.java"); // // 起動プロセスのstdout // InputStream isout = process.getInputStream(); InputStreamReader isoutr = new InputStreamReader(isout, "EUC-JP"); BufferedReader brout = new BufferedReader(isoutr); // // 起動プロセスのstderr(使わないけど) // InputStream iserr = process.getErrorStream(); InputStreamReader iserrr = new InputStreamReader(iserr, "EUC-JP"); BufferedReader brerr = new BufferedReader(iserrr); // // 起動プロセスのstdin(使わないけど) // OutputStream osin = process.getOutputStream(); OutputStreamWriter osinr = new OutputStreamWriter(osin, "EUC-JP"); // // 結果受取り // String str; while ((str = brout.readLine()) != null) { System.out.println(str); } // // クローズ // brout.close(); isoutr.close(); isout.close(); brerr.close(); iserrr.close(); iserr.close(); osinr.close(); osin.close(); } catch (Exception e) { System.out.println(e); } } }
exec_program.java - 実行結果
-rw-r--r-- 1 m-ito users 3184 5月 31 00:51 class_test.java -rw-r--r-- 1 m-ito users 1206 6月 4 14:26 exec_program.java -rw-r--r-- 1 m-ito users 1317 6月 2 23:06 file_buffered_read.java -rw-r--r-- 1 m-ito users 687 6月 2 23:08 file_delete.java -rw-r--r-- 1 m-ito users 452 6月 4 12:45 file_mkdir.java -rw-r--r-- 1 m-ito users 1433 6月 4 14:22 file_printf.java -rw-r--r-- 1 m-ito users 769 6月 4 14:23 file_rename.java -rw-r--r-- 1 m-ito users 1094 6月 2 23:09 file_stream_read.java -rw-r--r-- 1 m-ito users 1579 6月 2 23:18 file_stream_write.java -rw-r--r-- 1 m-ito users 551 6月 2 23:20 for_test.java -rw-r--r-- 1 m-ito users 649 6月 2 23:24 function_test.java -rw-r--r-- 1 m-ito users 624 6月 4 14:25 get_datetime.java -rw-r--r-- 1 m-ito users 248 6月 2 23:24 getenv_test.java -rw-r--r-- 1 m-ito users 195 6月 4 12:43 hello.java -rw-r--r-- 1 m-ito users 886 6月 2 23:44 if_test.java -rw-r--r-- 1 m-ito users 369 6月 4 16:00 string_hikisu.java -rw-r--r-- 1 m-ito users 313 6月 4 15:53 string_indexOf.java -rw-r--r-- 1 m-ito users 423 6月 4 15:54 string_length.java -rw-r--r-- 1 m-ito users 706 6月 4 15:55 string_mojihenkan.java -rw-r--r-- 1 m-ito users 431 6月 4 15:56 string_replaceAll.java -rw-r--r-- 1 m-ito users 620 6月 4 15:56 string_split.java -rw-r--r-- 1 m-ito users 722 6月 4 15:59 string_substring.java -rw-r--r-- 1 m-ito users 417 5月 29 13:56 switch_test.java -rw-r--r-- 1 m-ito users 1229 6月 4 12:21 tcpip_client.java -rw-r--r-- 1 m-ito users 1698 6月 4 12:30 tcpip_multi_server.java -rw-r--r-- 1 m-ito users 1227 6月 4 12:38 tcpip_server.java -rw-r--r-- 1 m-ito users 1155 6月 2 13:28 thread_test.java -rw-r--r-- 1 m-ito users 991 6月 4 15:52 var.java -rw-r--r-- 1 m-ito users 764 6月 4 16:01 var_array.java -rw-r--r-- 1 m-ito users 1088 6月 4 15:58 var_hash.java -rw-r--r-- 1 m-ito users 871 6月 4 15:51 var_henkan.java -rw-r--r-- 1 m-ito users 448 6月 4 12:39 while_test.java
exec_program.java - OSコマンド実行(単純起動)
// // 「外部コマンド実行」テスト // // compile : javac -encoding utf-8 exec_program.java // run : java -cp . exec_program // import java.io.*; public class exec_program { public static void main(String[] args) { try { // // 実行 // Process process = Runtime.getRuntime().exec("ls -al *.java"); // // 終了を待ち合わせる // int ret = process.waitFor(); } catch (Exception e) { System.out.println(e); } } }
file_stream_write.java - ファイル出力
// // 「ファイル出力(ストリーム)」テスト // // compile : javac -encoding utf-8 file_stream_write.java // run : java -cp . file_stream_write // import java.io.*; public class file_stream_write { public static void main(String[] args) { // // ファイルへの出力 // try { FileOutputStream fos = new FileOutputStream("file_stream_write.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos, "EUC-JP"); osw.write("これは line1\n"); osw.write("これは line2\n"); osw.write("これは line3\n"); osw.write("これは line4\n"); osw.write("これは line5\n"); osw.close(); fos.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } // // 標準出力への出力 // try { OutputStreamWriter osw = new OutputStreamWriter(System.out, "EUC-JP"); osw.write("this is line1 to stdout\n"); osw.write("this is line2 to stdout\n"); osw.write("this is line3 to stdout\n"); osw.write("this is line4 to stdout\n"); osw.write("this is line5 to stdout\n"); osw.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } // // エラー出力への出力 // try { OutputStreamWriter osw = new OutputStreamWriter(System.err, "EUC-JP"); osw.write("this is line1 to stderr\n"); osw.write("this is line2 to stderr\n"); osw.write("this is line3 to stderr\n"); osw.write("this is line4 to stderr\n"); osw.write("this is line5 to stderr\n"); osw.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } } }
file_stream_write.java - 実行結果
$ java file_stream_write this is line1 to stdout this is line2 to stdout this is line3 to stdout this is line4 to stdout this is line5 to stdout this is line1 to stderr this is line2 to stderr this is line3 to stderr this is line4 to stderr this is line5 to stderr $ cat file_stream_write.txt これは line1 これは line2 これは line3 これは line4 これは line5
【追記】追加書き込み
中核部分だけ
FileOutputStream fos = new FileOutputStream("file_stream_write.txt", true); OutputStreamWriter osw = new OutputStreamWriter(fos, "EUC-JP"); osw.write("この行は最後に追加されます。\n"); osw.close(); fos.close();
file_printf.java - 書式付きファイル出力
// // 「printf」テスト // // compile : javac -encoding utf-8 file_printf.java // run : java -cp . file_printf // import java.io.*; public class file_printf { public static void main(String[] args) { // // ファイルへの出力 // try { FileOutputStream fos = new FileOutputStream("file_printf.txt"); // // "true" in second argument means "auto flush" // PrintStream ps = new PrintStream(fos, true, "EUC-JP"); for (int i = 0; i < 3; i++){ ps.printf("i = %d, i*i = %d, 3.14*i*i = %f\n", i, i*i , 3.14*i*i); } ps.close(); fos.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } // // 標準出力への出力 // try { PrintStream ps = new PrintStream(System.out, true, "EUC-JP"); for (int i = 0; i < 3; i++){ ps.printf("i = %d, i*i = %d, 3.14*i*i = %f to stdout\n", i, i*i , 3.14*i*i); } ps.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } // // エラー出力への出力 // try { PrintStream ps = new PrintStream(System.err, true, "EUC-JP"); for (int i = 0; i < 3; i++){ ps.printf("i = %d, i*i = %d, 3.14*i*i = %f to stderr\n", i, i*i , 3.14*i*i); } ps.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } // // 標準出力、エラー出力への出力の別解 // // System.out.printf("This printf is right too! to stdout\n"); // System.err.printf("This printf is right too! to stderr\n"); } }
file_printf.java - 実行結果
$ java file_printf i = 0, i*i = 0, 3.14*i*i = 0.000000 to stdout i = 1, i*i = 1, 3.14*i*i = 3.140000 to stdout i = 2, i*i = 4, 3.14*i*i = 12.560000 to stdout i = 0, i*i = 0, 3.14*i*i = 0.000000 to stderr i = 1, i*i = 1, 3.14*i*i = 3.140000 to stderr i = 2, i*i = 4, 3.14*i*i = 12.560000 to stderr $ cat file_printf.txt i = 0, i*i = 0, 3.14*i*i = 0.000000 i = 1, i*i = 1, 3.14*i*i = 3.140000 i = 2, i*i = 4, 3.14*i*i = 12.560000
【追記】書式付き文字列変換
中核部分だけ抜粋
FileOutputStream fos = new FileOutputStream("file_stream_write.txt"); // OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); // OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-16"); // OutputStreamWriter osw = new OutputStreamWriter(fos, "Shift_JIS"); OutputStreamWriter osw = new OutputStreamWriter(fos, "EUC-JP"); osw.write(String.format("%s\n", "これは line1")); osw.close(); fos.close();
file_stream_read.java - ファイル入力(ストリーム)
// // 「ファイル入力(ストリーム)」テスト // // compile : javac -encoding utf-8 file_stream_read.java // run : java -cp . file_stream_read // import java.io.*; public class file_stream_read { public static void main(String[] args) { // // ファイルからの入力 // try { FileInputStream fis = new FileInputStream("file_stream_write.txt"); InputStreamReader isr = new InputStreamReader(fis, "EUC_JP"); int ch; // // fis.read() を使うと変換せずに(バイナリファイルとして)読み込んで来る。 // isr.read() はunicodeに変換しながら読み込んで来る。 // while ((ch = isr.read()) != -1){ System.out.print((char)ch); } isr.close(); fis.close(); } catch(IOException e) { System.out.println("read error happened : " + e); } finally { } // // 標準入力からの入力 // System.out.println("Please input something : "); try { InputStreamReader isr = new InputStreamReader(System.in, "EUC-JP"); int ch; while ((ch = isr.read()) != -1){ System.out.print((char)ch); } isr.close(); } catch(IOException e) { System.out.println("read error happened : " + e); } finally { } } }
file_stream_read.java - 実行結果
これは line1 これは line2 これは line3 これは line4 これは line5 Please input something : This is java. This is java. ^D
file_buffered_read.java - ファイル入力(行単位)
// // 「ファイル入力(バッファード)」テスト // // compile : javac -encoding utf-8 file_buffered_read.java // run : java -cp . file_buffered_read // import java.io.*; public class file_buffered_read { public static void main(String[] args) { // // ファイルからの入力 // try { // ファイル開く(文字コード変換無し) FileInputStream fis = new FileInputStream("file_stream_write.txt"); // 入力ストリーム(文字コード変換あり EUC-JP -> UNICODE) InputStreamReader isr = new InputStreamReader(fis, "EUC-JP"); // 行入力ストリーム BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); isr.close(); fis.close(); } catch(IOException e) { System.out.println("read error happened : " + e); } finally { } // // 標準入力からの入力 // System.out.println("Please input something : "); try { // 入力ストリーム(文字コード変換あり EUC-JP -> UNICODE) InputStreamReader isr = new InputStreamReader(System.in, "EUC-JP"); // 行入力ストリーム BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); isr.close(); } catch(IOException e) { System.out.println("read error happened : " + e); } finally { } } }
file_buffered_read.java - 実行結果
これは line1 これは line2 これは line3 これは line4 これは line5 Please input something : This is java. This is java. ^D
file_delete.java - ファイル削除
// // 「delete」テスト // // compile : javac -encoding utf-8 file_delete.java // run : java -cp . file_delete // import java.io.*; public class file_delete { public static void main(String[] args) { // // 準備 // try { FileOutputStream fos = new FileOutputStream("file_delete.txt"); PrintStream ps = new PrintStream(fos, true, "EUC-JP"); ps.printf("dummy data\n"); ps.close(); fos.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } // // 削除 // java.io.File f = new java.io.File("file_delete.txt"); if (f.delete()){ System.out.println("delete success"); }else{ System.out.println("delete failure"); } } }
file_delete.java - 実行結果
delete success
file_rename.java - ファイル名変更
// // 「rename」テスト // // compile : javac -encoding utf-8 file_rename.java // run : java -cp . file_rename // import java.io.*; public class file_rename { public static void main(String[] args) { // // 準備 // try { FileOutputStream fos = new FileOutputStream("file_rename.txt"); PrintStream ps = new PrintStream(fos, true, "EUC-JP"); ps.printf("dummy data\n"); ps.close(); fos.close(); } catch(IOException e) { System.out.println("write error happened : " + e); } finally { } // // リネーム // java.io.File before = new java.io.File("file_rename.txt"); java.io.File after = new java.io.File("FILE_RENAME.TXT"); if (before.renameTo(after)){ System.out.println("rename success"); }else{ System.out.println("rename failure"); } } }
file_rename.java - 実行結果
rename success $ ls | egrep -i file_rename.txt FILE_RENAME.TXT
file_mkdir.java - ディレクトリ作成
// // 「mkdir」テスト // // compile : javac -encoding utf-8 file_mkdir.java // run : java -cp . file_mkdir // import java.io.*; public class file_mkdir { public static void main(String[] args) { // // 準備 // java.io.File d = new java.io.File("file_mkdir.dir"); d.delete(); // // ディレクトリ作成 // d = new java.io.File("file_mkdir.dir"); if (d.mkdir()){ System.out.println("mkdir success"); }else{ System.out.println("mkdir failure"); } } }
file_mkdir.java - 実行結果
mkdir success $ ls -ald file_mkdir.dir drwxr-xr-x 2 m-ito users 4096 6月 5 22:51 file_mkdir.dir/
class_test.java - クラス
// // 「class」テスト // // compile : javac -encoding utf-8 class_test.java // run : java -cp . class_test // // 一つのjavaソース内で、publicで宣言できるclassは一つだけ。 // なので、外部から参照されるクラス定義は独立したファイルで // 作成する必要がある。 // public class class_test { public static void main(String[] args) { class_test_my_class mc1 = new class_test_my_class(); System.out.println("mc1 wk_class = " + mc1.get_wk_class()); System.out.println("mc1 wk_instance = " + mc1.get_wk_instance()); class_test_my_class mc2 = new class_test_my_class("WK_CLASS2", "WK_INSTANCE2"); System.out.println("mc2 wk_class = " + mc2.get_wk_class()); System.out.println("mc2 wk_instance = " + mc2.get_wk_instance()); mc1.set_wk_class("WK_CLASS1"); mc1.set_wk_instance("WK_INSTANCE1"); System.out.println("mc1 wk_class = " + mc1.get_wk_class()); System.out.println("mc1 wk_instance = " + mc1.get_wk_instance()); System.out.println("mc2 wk_class = " + mc2.get_wk_class()); System.out.println("mc2 wk_instance = " + mc2.get_wk_instance()); class_test_my_class2 mc3 = new class_test_my_class2(); System.out.println("mc3 wk_class = " + mc3.get_wk_class()); System.out.println("mc3 wk_instance = " + mc3.get_wk_instance()); System.out.println("mc3 wk_class2 = " + mc3.get_wk_class2()); System.out.println("mc3 wk_instance2 = " + mc3.get_wk_instance2()); mc3.set_wk_class("WK_CLASS3"); mc3.set_wk_instance("WK_INSTANCE3"); System.out.println("mc3 wk_class = " + mc3.get_wk_class()); System.out.println("mc3 wk_instance = " + mc3.get_wk_instance()); class_test_my_class2 mc4 = new class_test_my_class2("AAAAA", "BBBBB", "CCCCC", "DDDDD"); System.out.println("mc4 wk_class = " + mc4.get_wk_class()); System.out.println("mc4 wk_instance = " + mc4.get_wk_instance()); System.out.println("mc4 wk_class2 = " + mc4.get_wk_class2()); System.out.println("mc4 wk_instance2 = " + mc4.get_wk_instance2()); } } // // クラス(継承無し) // class class_test_my_class { // // クラス変数(このクラスから生成されたオブジェクト間で共通の領域) // static String wk_class; // // インスタンス変数(オブジェクトごとに独立したな領域) // String wk_instance; // 指定無し 自ソースファイルのみからアクセスできる。 // public どこからも全く自由にアクセスできる。 // protected 自ソースファイルと、サブクラスのみからアクセスできる。 // private 自分自身のクラスのみからアクセスできる。 // // コンストラクタ1(初期化メソッド) // class_test_my_class(){ wk_class = "initial wk_class"; wk_instance = "initial wk_instance"; } // // コンストラクタ2(初期化メソッド) // class_test_my_class(String arg_class, String arg_instance){ wk_class = arg_class; wk_instance = arg_instance; } // // メソッド // String get_wk_class(){ return wk_class; } String get_wk_instance(){ return wk_instance; } void set_wk_class(String str){ wk_class = str; } void set_wk_instance(String str){ wk_instance = str; } void speak(){ System.out.println("wk_class=" + wk_class); System.out.println("wk_instance=" + wk_instance); } }
static で宣言された変数(およびメソッド)はクラス定義そのものの中に実体が有り、該当のクラスから生成されたオブジェクト間で共有される。
メソッドの名称がクラス名と同一のものはオブジェクトの初期化メソッド(コンストラクタと呼ぶ)となり、new(生成)の際に自動的に実行される。また、引数の違いにより複数の初期化メソッドを定義できる。
// // クラス (class_test_my_classから継承) // class class_test_my_class2 extends class_test_my_class { // // クラス変数(このクラスから生成されたオブジェクト間で共通の領域) // static String wk_class2; // // インスタンス変数(オブジェクトごとに独立したな領域) // String wk_instance2; // // コンストラクタ(1) // class_test_my_class2(){ wk_class2 = "initial wk_class2"; wk_instance2 = "initial wk_instance2"; } // // コンストラクタ(2) // class_test_my_class2(String arg_class, String arg_instance){ wk_class2 = arg_class; wk_instance2 = arg_instance; } // // コンストラクタ(3) // class_test_my_class2(String arg_class1, String arg_instance1, String arg_class2, String arg_instance2){ // 親クラスのコンストラクタの呼び出し super(arg_class1, arg_instance1); wk_class2 = arg_class2; wk_instance2 = arg_instance2; // 意味は無いけど、親のメソッドを呼び出してみる super.speak(); } // // メソッド // String get_wk_class2(){ return wk_class2; } String get_wk_instance2(){ return wk_instance2; } void set_wk_class2(String str){ wk_class2 = str; } void set_wk_instance2(String str){ wk_instance2 = str; } // // 再定義(オーバーライド) // void set_wk_class(String str){ wk_class = str + " is setted in class_test_my_class2"; } void set_wk_instance(String str){ wk_instance = str + " is setted in class_test_my_class2"; } }
クラスの継承は extends にて指定する。
コンストラクタからは親のコンストラクタが引数無しで自動的に呼ばれる。明示的に呼び出す場合は super(引数,...) の形式で呼び出す。
親のメソッド、変数は super.メソッド(引数,...)、super.変数 の形式で呼び出す。
親で定義されたメソッドと同名のメソッドを定義する事で、親のメソッドを置き換える(再定義)することが出来る。
class_test.java - 実行結果
mc1 wk_class = initial wk_class mc1 wk_instance = initial wk_instance mc2 wk_class = WK_CLASS2 mc2 wk_instance = WK_INSTANCE2 mc1 wk_class = WK_CLASS1 mc1 wk_instance = WK_INSTANCE1 mc2 wk_class = WK_CLASS1 mc2 wk_instance = WK_INSTANCE2 mc3 wk_class = initial wk_class mc3 wk_instance = initial wk_instance mc3 wk_class2 = initial wk_class2 mc3 wk_instance2 = initial wk_instance2 mc3 wk_class = WK_CLASS3 is setted in class_test_my_class2 mc3 wk_instance = WK_INSTANCE3 is setted in class_test_my_class2 wk_class=AAAAA wk_instance=BBBBB mc4 wk_class = AAAAA mc4 wk_instance = BBBBB mc4 wk_class2 = CCCCC mc4 wk_instance2 = DDDDD
class_test2.java - クラス(多態性)
// // 「class(多態性)」テスト // // compile : javac -encoding utf-8 class_test2.java // run : java -cp . class_test2 // class class_test2 { public static void main(String[] args){ test1 t1 = new test1("test1"); // test1クラスにtest1オブジェクトを放り込む -> 当然 test2 t2 = new test2("test21", "test22"); // test2クラスにtest2オブジェクトを放り込む -> 当然 test1 t11 = new test2("test111", "test112"); // test1クラスにtest2オブジェクトを放り込む -> これが多態性! t1.show(); // test1オブジェクトのshow()を実行 t2.show(); // test2オブジェクトのshow()を実行 t11.show(); // test1オブジェクトからtest2のshow()を実行 } } // class test1 { String str1; test1(String s){ str1 = s; } void show(){ System.out.println(str1); } } // class test2 extends test1 { String str2; test2(String s1, String s2){ super(s1); str2 = s2; } void show(){ System.out.println(str1 + "+" + str2); } }
親クラスは子クラスを格納できる。これ多態性。
- メモリ上に確保されたtest2クラスのオブジェクトの実体は以下を要素として持つ
- String str1 <- test1で定義したもの
- String str2 <- test2で定義したもの
- void show() <- test2でオーバーライトしたもの
- test1 t11は上記のオブジェクトをポイントする。
- t11経由ではtest1の要素である以下のもののみアクセス(t11.ほげ)できる
- String str1
- void show()
ただし、メモリ上に確保されたtest2クラスのオブジェクトの実体内部では、当然全ての要素にアクセスできるので、test1のオブジェクトであるt11を経由して呼び出すshow()メソッドもString str2にアクセスすることが出来、正しく動作する。
class_test2.java - 実行結果
test1 test21+test22 test111+test112
class_test3.java - クラス(多態性2)
// // 「class(多態性2)」テスト // // compile : javac -encoding utf-8 class_test3.java // run : java -cp . class_test3 // class class_test3 { public static void main(String[] args){ test2 t2 = new test1("test1"); t2.show(); } } // class test1 { String str1; test1(String s){ str1 = s; } void show(){ System.out.println(str1); } } // class test2 extends test1 { String str2; test2(String s1, String s2){ super(s1); str2 = s2; } void show(){ System.out.println(str1 + "+" + str2); } }
子クラスは親クラスを格納できない。で、以下のようなコンパイルエラーが発生する。
class_test3.java - 実行結果
507 m-ito@lib190:~/src/java$ javac -encoding utf-8 !$ javac -encoding utf-8 class_test3.java class_test3.java:3: 互換性のない型 検出値 : test1 期待値 : test2 test2 t2 = new test1("test1"); ^ エラー 1 個
- メモリ上に確保されたtest1クラスのオブジェクトの実体は以下を要素として持つ
- String str1
- void show()
- test2 t2は上記のオブジェクトをポイントする。
この場合、t2.str2の実体がどこにも存在しないことになり不都合なので、javaコンパイラーはエラーを起こす(報告してくれる)。
implements_test.java - インターフェース
// // 「implements」テスト // // compile : javac -encoding utf-8 implements_test.java // run : java -cp . implements_test // // // インターフェース // interface interface1 { void message1(); } // // クラス // class super_class { public void message2() { System.out.println("super_class.message2"); } } // class class1 extends super_class implements interface1 { public void message1() { System.out.println("class1.message1"); } } // class class2 implements interface1 { public void message1() { System.out.println("class2.message1"); } } public class implements_test { public static void main(String[] args) { interface1 ip1 = new class1(); interface1 ip2 = new class2(); ip1.message1(); ip2.message1(); } }
インターフェース(interface1)で宣言された変数 ip1, ip2には、同じインターフェースをインプリメントしたクラス(class1, class2)から生成したオブジェクトであれば何でも格納できる。
正直、現時点ではそのメリットを理解できてるとは言い難い。まぁ有る程度の経験値を積めば、有る日いきなり雲が晴れたかのように理解できる事もあろうか...。
implements_test.java - 実行結果
class1.message1 class2.message1
thread_test.java - スレッド
// // 「thread」テスト // // compile : javac -encoding utf-8 thread_test.java // run : java -cp . thread_test // import java.io.*; public class thread_test { public static void main(String[] args) { called_thread ct = new called_thread("first_arg", "second_arg"); ct.start(); called_thread2 ct2 = new called_thread2("first_arg", "second_arg"); Thread th = new Thread(ct2); th.start(); try { ct.join(); // ctスレッドの終了を待つ th.join(); // thスレッドの終了を待つ catch (InterruptedException e){ System.out.println("join fail : " + e); } } } class called_thread extends Thread { // // インスタンス変数(引数の受け皿) // String arg1, arg2; // // コンストラクタ(引数受け取り) // called_thread(String arg1, String arg2){ this.arg1 = arg1; this.arg2 = arg2; } // // スレッド処理の本体 // public void run (){ System.out.println("called_thread with arg1 = " + arg1 + ", arg2 = " + arg2); } } class called_thread2 /* extends hoge */ implements Runnable { // // インスタンス変数(引数の受け皿) // String arg1, arg2; // // コンストラクタ(引数受け取り) // called_thread2(String arg1, String arg2){ this.arg1 = arg1; this.arg2 = arg2; } // // スレッド処理の本体 // public void run (){ System.out.println("called_thread2 with arg1 = " + arg1 + ", arg2 = " + arg2); } }
thread_test.java - 実行結果
called_thread with arg1 = first_arg, arg2 = second_arg called_thread2 with arg1 = first_arg, arg2 = second_arg
thread_sync_test.java - スレッド
// // 「thread(synchronized)」テスト // // compile : javac -encoding utf-8 thread_sync_test.java // run : java -cp . thread_sync_test // import java.io.*; public class thread_sync_test { public static void main(String[] args){ called_thread[] ct = new called_thread[10]; counter cnt_non_threadsafe = new counter_non_threadsafe(); counter cnt_threadsafe = new counter_threadsafe(); // // NON thread safe section // for (int i = 0; i < 10; i++){ ct[i] = new called_thread(cnt_non_threadsafe); ct[i].start(); } try { for (int i = 0; i < 10; i++){ ct[i].join(); } }catch (InterruptedException e){ System.out.println("join fail : " + e); } System.out.println("non thread safe counter = " + cnt_non_threadsafe.get()); // // thread safe section // for (int i = 0; i < 10; i++){ ct[i] = new called_thread(cnt_threadsafe); ct[i].start(); } try { for (int i = 0; i < 10; i++){ ct[i].join(); } }catch (InterruptedException e){ System.out.println("join fail : " + e); } System.out.println("thread safe counter = " + cnt_threadsafe.get()); } } interface counter { void up(); int get(); } class counter_non_threadsafe implements counter { int data; void counter_non_threadsafe(){ data = 0; } public /* synchronized */ void up(){ int tmp; tmp = data; try { Thread.sleep(1000); }catch (InterruptedException e){ System.out.println("sleep fail : " + e); } data = tmp + 1; } public int get(){ return data; } } class counter_threadsafe implements counter { int data; void counter_threadsafe(){ data = 0; } public synchronized void up(){ int tmp; tmp = data; try { Thread.sleep(1000); }catch (InterruptedException e){ System.out.println("sleep fail : " + e); } data = tmp + 1; } public int get(){ return data; } } class called_thread extends Thread { // // インスタンス変数(引数の受け皿) // counter cnt; // // コンストラクタ(引数受け取り) // called_thread(counter cnt){ this.cnt = cnt; } // // スレッド処理の本体 // public void run (){ System.out.println("run called_thread"); cnt.up(); } }
thread_sync_test.java - 実行結果
run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread non thread safe counter = 1 run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread thread safe counter = 10
thread_waitnotify_test.java - スレッド
// // 「thread(wait, notify)」テスト // // compile : javac -encoding utf-8 thread_waitnotify_test.java // run : java -cp . thread_waitnotify_test // import java.io.*; // // メインクラス // public class thread_waitnotify_test { public static void main(String[] args){ called_thread[] ct = new called_thread[10]; counter cnt = new counter(0 /* カウンターの初期値 */, 1 /* 同時アクセス可能スレッド数 */); // // スレッドの起動 // for (int i = 0; i < ct.length; i++){ ct[i] = new called_thread(cnt); ct[i].start(); } // // スレッド終了の待ち合わせ // try { for (int i = 0; i < ct.length; i++){ ct[i].join(); } }catch (InterruptedException e){ System.out.println("join fail : " + e); } System.out.println("thread safe counter = " + cnt.get()); } } // // wait(), notifyAll(), セマフォ変数(sem)を利用した、同時アクセス可能スレッド数を指定した // lock(), unlock()メソッドを持つcounterクラス // class counter { int init_sem, sem; int data; // // コンストラクタ(カウンタの初期値、同時アクセスを許すスレッド数) // counter(int data, int sem){ this.data = data; init_sem = this.sem = sem; } // // ロックメソッド // synchronized void lock(){ if (sem <= 0){ try { while (sem <= 0){ wait(); } sem--; }catch (InterruptedException e){ System.out.println("wait fail : " + e); } }else{ sem--; } } // // アンロックメソッド // synchronized void unlock(){ if (sem < init_sem){ sem++; notifyAll(); } } // // カウントアップメソッド // // lock(),unlock()で排他制御を行うので、あえてsynchronized修飾していない // void up(){ int tmp; tmp = data; try { Thread.sleep(1000); }catch (InterruptedException e){ System.out.println("sleep fail : " + e); } data = tmp + 1; } // // カウンター値取得 // int get(){ return data; } } // // スレッドの本体クラス // class called_thread extends Thread { // // インスタンス変数(引数の受け皿) // counter cnt; // // コンストラクタ(引数受け取り) // called_thread(counter cnt){ this.cnt = cnt; } // // スレッド処理の本体 // public void run (){ System.out.println("run called_thread"); cnt.lock(); cnt.up(); cnt.unlock(); } }
thread_waitnotify_test.java - 実行結果
run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread run called_thread thread safe counter = 10
tcpip_client.java - TCP/IPクライアント
// // 「tcp/ip クライアント」テスト // // compile : javac -encoding utf-8 tcpip_client.java // run : java -cp . tcpip_client // import java.io.*; import java.net.*; public class tcpip_client { public static void main(String[] args) throws IOException { // // throws IOException => 自分を呼び出したメソッドに例外処理を委譲する。 // Socket socket; BufferedReader br; BufferedWriter bw; // // サーバへ接続するためのソケットオープン // socket = new Socket("localhost", 12345); // // サーバからの受信ストリーム開く(行アクセス) // br = new BufferedReader(new InputStreamReader(socket.getInputStream())); // // サーバへの送信ストリーム開く(行アクセス) // bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // // 送信電文の準備 // String outstr = "テスト電文です"; // // サーバへ電文送信 // bw.write(outstr, 0, outstr.length()); // // サーバへ改行送信 // bw.newLine(); // // サーバへの送信を強制出力 // bw.flush(); // // サーバからレスポンスを受信 // String instr; if ((instr = br.readLine()) == null){ System.out.println("受信エラー"); }else{ System.out.println(instr); } // // ストリーム、ソケットを閉じる // bw.close(); br.close(); socket.close(); } }
tcpip_server.java - TCP/IPサーバ(シングルサーバ)
// // 「tcp/ip サーバ」テスト // // compile : javac -encoding utf-8 tcpip_server.java // run : java -cp . tcpip_server // import java.io.*; import java.net.*; public class tcpip_server { public static void main(String[] args) throws IOException { ServerSocket serverSocket; Socket socket; BufferedReader in; BufferedWriter out; String line; // // クライアントからの電文を受信するソケットを開く // serverSocket = new ServerSocket(12345); // // 受信ループ // while (true){ // // クライアントからの受信を待つ & 送受信のためのソケットを得る // socket = serverSocket.accept(); // // クライアントからの受信ストリーム // in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // // クライアントへの送信ストリーム // out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // // 送受信ループ // while ((line = in.readLine()) != null){ if (line.compareTo("END") == 0){ break; } // // クライアントへ送信(echo backするだけ) // out.write(line); out.newLine(); out.flush(); } // // ストリーム、ソケットを閉じる // out.close(); in.close(); socket.close(); // if (line != null){ if (line.compareTo("END") == 0){ break; } } } } }
tcpip_multi_server.java - TCP/IPサーバ(マルチスレッド)
// // 「tcp/ip サーバ(マルチスレッド版)」テスト // // compile : javac -encoding utf-8 tcpip_multi_server.java // run : java -cp . tcpip_multi_server // import java.io.*; import java.net.*; public class tcpip_multi_server { public static void main(String[] args) throws IOException { ServerSocket serverSocket; Socket socket; // // クライアントからの電文を受信するソケットを開く // serverSocket = new ServerSocket(12345); // // 受信ループ // while (true){ // // クライアントからの受信を待つ & 送受信のためのソケットを得る // socket = serverSocket.accept(); // // 送受信処理のためのスレッドを起動する。 // 起動されたスレッドはバックグラウンドで並行して実行される。 // ループの先頭に戻り次の受信を待つ。 // thread_main tm = new thread_main(socket); tm.start(); } } } // // 送受信クラス // class thread_main extends Thread { // // インスタンス変数(送受信ソケット) // Socket socket; // // コンストラクタ(ソケット取得) // thread_main (Socket socket){ this.setDaemon(true); this.socket = socket; } // // スレッドの主処理 // public void run() { try { // // クライアントからの受信ストリーム // BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // // クライアントへの送信ストリーム // BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // // 送受信ループ // String line; while ((line = in.readLine()) != null){ if (line.compareTo("END") == 0){ break; } // // クライアントへ送信(echo backするだけ) // out.write(line); out.newLine(); out.flush(); } // // ストリーム、ソケットを閉じる // out.close(); in.close(); socket.close(); }catch (IOException e){ } } }
そう、後で知った事だが、Javaのクラス名称は大文字で始めるのが習慣らしい。上記のサンプルはそれを知る前に作ったので、クラス名称が全て小文字で始まっている。あしからず。
Package文
MyPackage/Package_test.java
package MyPackage; public class Package_test { public void message (){ System.out.println("MyPackage.Package_test is called"); } }
上記のソースは他人に配布して利用してもらう前提のパッケージである。
「package MyPackage」でパッケージ名を宣言し、同名のディレクトリにソースを作成する。
Package_main_test.java
import MyPackage.*; public class Package_main_test { public static void main(String[] args){ Package_test mp = new Package_test(); mp.message(); } }
「MyPackage」を利用する場合は「import MyPackage.*;」で利用を宣言する。
Package文 - 実行結果
$ javac -encoding utf-8 MyPackage/Package_test.java $ javac -encoding utf-8 Package_main_test.java $ java Package_main_test MyPackage.Package_test is called
パッケージを配布する場合は
$ jar cf MyPackage.jar MyPackage/
として「MyPackage.jar」を作成し、これを配布する。
配布された側では
$ java -cp .:MyPackage.jar Package_main_test
のように「-cp .:MyPackage.jar」を指定してして実行する。もしくは環境変数 CLASSPATHに設定して実行する。
main()を含み複数のclassから成るアプリケーションをjarにまとめて実行する
JarTest.java
public class JarTest { public static void main(String[] args) { JarTestSub jt = new JarTestSub(); jt.hello(); } } class JarTestSub { public void hello(){ System.out.println("Hello."); } }
jarファイル作成等
コンパイル
$ javac -encoding utf-8 JarTest.java $ ls -al JarTest*class -rw-r--r-- 1 m-ito m-ito 318 5月 30 12:22 JarTest.class -rw-r--r-- 1 m-ito m-ito 393 5月 30 12:22 JarTestSub.class
jarファイル作成
$ jar cvf JarTest.jar JarTest.class JarTestSub.class マニフェストが追加されました。 JarTest.class を追加中です。(入 = 318) (出 = 239)(24% 収縮されました) JarTestSub.class を追加中です。(入 = 393) (出 = 279)(29% 収縮されました) $ ls -al JarTest.jar -rw-r--r-- 1 m-ito m-ito 1105 5月 30 12:23 JarTest.jar
マニフェストファイル取り出しのためにjarファイルを展開する
$ jar xvf JarTest.jar META-INF/ が作成されました。 META-INF/MANIFEST.MF が展開されました。 JarTest.class が展開されました。 JarTestSub.class が展開されました。
マニフェストファイルにMain-Classの指定を追加する
$ vi META-INF/MANIFEST.MF Main-Class: JarTest
$ cat META-INF/MANIFEST.MF Manifest-Version: 1.0 Created-By: 1.6.0_43 (Sun Microsystems Inc.) Main-Class: JarTest
jarファイルにマニフェストファイルを加えて再作成する
$ jar cvfm JarTest.jar META-INF/MANIFEST.MF JarTest.class JarTestSub.class マニフェストが追加されました。 JarTest.class を追加中です。(入 = 318) (出 = 239)(24% 収縮されました) JarTestSub.class を追加中です。(入 = 393) (出 = 279)(29% 収縮されました)
実行してみる
$ java -jar JarTest.jar Hello.
[追記]jarファイルの実行の別解
mainメソッドを含むMainクラスとその他もろもろのクラスをまとめて、Main.jarを作成したとする。
$ jar cf Main.jar Main.class Hoge1.class Hoge2.class ...
Main.jarが別のFoo1.jar、Foo2.jar、Foo3.jarに依存するとした場合、Main.jarは以下のように実行する。
$ java -cp Foo1.jar:Foo2.jar:Foo3.jar:Main.jar Main
java -cp {依存するjar}:...:{依存するjar}:{mainメソッドを含むjar} {mainメソッドを含むクラス名}
また、マニフェストファイルに、
Class-Path: Foo1.jar:Foo2.jar:Foo3.jar Main-Class: Main
を追記して、Main.jarを作成すれば、
$ java -jar Main.jar
で実行できる。
io_test.java - 入出力関係の今一度のまとめ...
// // 「Input/Output全般」テスト // // compile : javac -encoding utf-8 io_test.java // run : java -cp . io_test // import java.io.*; public class io_test { public static void main(String[] args) throws Exception { //============================================================ // Output //============================================================ //------------------------------------------------------------ // DataOutputStream //------------------------------------------------------------ // // o バイナリデータの出力を行う // o 出力するデータは byte配列、int、long 等の基本型 // // OutputStream os = socket.getOutputStream(); // ソケットへ出力 // OutputStream os = process.getOutputStream(); // プロセスのstdinへ出力 // OutputStream os = System.out; // stdoutへ出力 // OutputStream os = new FileOutputStream("io_test_dos.dat"); // ファイルへ出力 DataOutputStream dos = new DataOutputStream(os); byte[] b = new byte[10]; b[0] = 0; b[1] = 1; b[2] = 2; dos.write(b, 0, 3); dos.writeByte(3); dos.writeInt(4); dos.flush(); dos.close(); //------------------------------------------------------------ // OutputStreamWriter //------------------------------------------------------------ // // o テキストデータの出力を行う // o 出力するデータはStringオブジェクト // o 文字コード変換が行われる // // 実際のコーディング中では(下記の)BufferedWriterでラップして利用するのが // 望ましい。 // os = new FileOutputStream("io_test_osw.txt"); OutputStreamWriter osw = new OutputStreamWriter(os, "EUC_JP"); String s = "文字列desu"; osw.write(s); osw.write("\n"); osw.write(s, 2, 3); osw.write("\n"); osw.flush(); osw.close(); //------------------------------------------------------------ // BufferedWriter //------------------------------------------------------------ // // o テキストデータの出力を行う // o 出力するデータはStringオブジェクト // o 文字コード変換が行われる // o 出力は適切にバッファリングされる // os = new FileOutputStream("io_test_bw.txt"); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "EUC_JP")); bw.write(s); bw.newLine(); bw.write(s, 2, 3); bw.newLine(); bw.flush(); bw.close(); //------------------------------------------------------------ // PrintStream //------------------------------------------------------------ // // o テキストデータの出力を行う // o 出力するデータをフォーマット可能 // o 文字コード変換が行われる // o 出力は適切にバッファリングされる // os = new FileOutputStream("io_test_ps.txt"); boolean auto_flush = true; PrintStream ps = new PrintStream(os, auto_flush, "EUC_JP"); ps.printf("%s\n", s); ps.flush(); ps.close(); //============================================================ // Input //============================================================ //------------------------------------------------------------ // DataInputStream //------------------------------------------------------------ // // o バイナリデータの入力を行う // o 入力するデータは byte配列、int、long 等の基本型 // // InputStream is = socket.getInputStream(); // ソケットから入力 // InputStream is = process.getInputStream(); // プロセスのstdoutから入力 // InputStream is = process.getErrorStream(); // プロセスのstderrから入力 // InputStream is = System.out; // stdinから入力 // InputStream is = System.err; // stderrから入力 // InputStream is = new FileInputStream("io_test_dos.dat"); // ファイルから入力 DataInputStream dis = new DataInputStream(is); byte[] dis_b_array = new byte[10]; dis.read(dis_b_array, 0, 3); byte dis_byte = dis.readByte(); int dis_int = dis.readInt(); dis.close(); System.out.println(String.format("dis_b_array[0] = %d", dis_b_array[0])); System.out.println(String.format("dis_b_array[1] = %d", dis_b_array[1])); System.out.println(String.format("dis_b_array[2] = %d", dis_b_array[2])); System.out.println(String.format("dis_byte = %d", dis_byte)); System.out.println(String.format("dis_int = %d", dis_int)); //------------------------------------------------------------ // InputStreamReader //------------------------------------------------------------ // // o テキストデータの入力を行う // o 入力するデータは char、char配列 // o 文字コード変換が行われる // // 実際のコーディング中では(下記の)BufferedReaderでラップして利用するのが // 望ましい。 // is = new FileInputStream("io_test_osw.txt"); InputStreamReader isr = new InputStreamReader(is, "EUC_JP"); int isr_c; char[] isr_c_array = new char[10]; isr_c = isr.read(); isr.read(isr_c_array, 0, 3); isr.close(); System.out.println(String.format("isr_c = %c", isr_c)); System.out.println(String.format("isr_c_array[0] = %c", isr_c_array[0])); System.out.println(String.format("isr_c_array[1] = %c", isr_c_array[1])); System.out.println(String.format("isr_c_array[2] = %c", isr_c_array[2])); //------------------------------------------------------------ // BufferedReader //------------------------------------------------------------ // // o テキストデータの入力を行う // o 入力するデータは char、char配列、Stringオブジェクト // o 文字コード変換が行われる // o 入力は適切にバッファリングされる // o 行入力が可能 // is = new FileInputStream("io_test_bw.txt"); BufferedReader br = new BufferedReader(new InputStreamReader(is, "EUC_JP")); int br_c; char[] br_c_array = new char[10]; br_c = br.read(); br.read(br_c_array, 0, 3); String br_s = br.readLine(); br.close(); System.out.println(String.format("br_c = %c", br_c)); System.out.println(String.format("br_c_array[0] = %c", br_c_array[0])); System.out.println(String.format("br_c_array[1] = %c", br_c_array[1])); System.out.println(String.format("br_c_array[2] = %c", br_c_array[2])); System.out.println("br_s = " + br_s); } }
io_test.java - 実行結果
$ java io_test dis_b_array[0] = 0 dis_b_array[1] = 1 dis_b_array[2] = 2 dis_byte = 3 dis_int = 4 isr_c = 文 isr_c_array[0] = 字 isr_c_array[1] = 列 isr_c_array[2] = d br_c = 文 br_c_array[0] = 字 br_c_array[1] = 列 br_c_array[2] = d br_s = esu
$ od -xc io_test_dos.dat 0000000 00 01 02 03 00 00 00 04 0100 0302 0000 0400 \0 001 002 003 \0 \0 \0 004 0000010
$ cat io_test_osw.txt 文字列desu 列de
$ cat io_test_bw.txt 文字列desu 列de
$ cat io_test_ps.txt 文字列desu
ThrowTest.java - 例外処理を行う
class MyException extends Exception { MyException(String msg){ super(msg); } } class ThrowTest { public static void main(String[] args){ ThrowTest m = new ThrowTest(); try { m.methodA(); }catch (MyException e){ System.out.println(e); }finally{ } } public void methodA() throws MyException { MyException e = new MyException("ERROR DESU!!"); throw e; } }
ThrowTest.java - 実行結果
MyException: ERROR DESU!!
その他もろもろ(未検証)
byte,char配列からStringへ変換
byte [] byte_arry = { 0x41, 0x42, 0x43 }; String str = new String(byte_arry); // String str = new String(byte_arry, "UTF-8");
char [] char_arry = { 0x61, 0x62, 0x63 }; String str = new String(char_arry); // String str = new String(char_arry, "US-ASCII");
Stringからbyte配列へ変換
String str = new String("abc"); byte [] byte_arry = str.getBytes(); // byte [] byte_arry = str.getBytes("UTF-8");
2009年06月14日 request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その3) [長年日記]
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その3)
どう考えても、いきなりこんなメッセージが出始めるのはおかしい。ここしばらくHDの調子が悪く、何回もfsckのお世話になっていたから、どこか致命的な壊れ方をしているのかもしれない(/libあたり...)。
とりあえず、良い機会なので現在のSlackware-10.1からSlackware-11.0にバージョンアップを行った。
なぜ最新のSlackware-12.2でなく、11.0かというと、12.0系はカーネルが2.6系かつinitrd.imgの肥大により、メモリーが64MBのlibretto100ではloadlinによるブートが出来なくなっていた事と、11.0がカーネル2.4系の最終ディストリビューションであることによる。
結構いろんなサーバ機能を構築していたので、それらの再構築に結構てまどったが、良い頭の体操になった感じ。作業経過はブログやウェブページに残しておくもんですな。
オリジナルのカーネルバージョンが2.4.33.3だったので、2.4.37.1をビルド中。
あっ、もちろん変なエラーメッセージは出なくなったよう。
2009年06月15日 request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その4) [長年日記]
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その4)
2.4.37.1をビルドしたらまた出た。一度オリジナルの2.4.33.3のコンフィグから make oldconfig して様子を見てみよう。
_ JVim 3.0-j2.1a の画面分割(split)
いまだに古いJvim(3.0-j2.1a)を使ってるのだけれども、今さらながら画面分割出来る事に気づいたのでメモする。
- :split ファイル名 : 分割したウインドウで指定したファイルを開く
- CTRL-W s : 今編集しているファイルを分割しウインドウで表示する
- CTRL-W n : 分割して空のウインドウを開く
- CTRL-W q : ウインドウを閉じ、編集を終了する
- CTRL-W c : ウインドウを閉じる
- CTRL-W o : 分割を中止し、現在編集中のファイルのみ表示する
- CTRL-W j : 下のウインドウに移動する
- CTRL-W k : 上のウインドウに移動する
- CTRL-W CTRL-W : 次のウインドウに移動する(ローテート)
- CTRL-W = : 各ウインドウの高さをそろえる
- CTRL-W - : ウインドウの高さを低くする
- CTRL-W + : ウインドウの高さを高くする
関連してバッファー操作
- :buffers or :files : 編集中バッファー一覧表示
- :buffer バッファ番号 : 指定バッファ表示
- :bnext : 次のバッファ表示
- :bprevious : 前のバッファー表示
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その5)
オリジナルの2.4.33.3のコンフィグから make oldconfig してもメッセージ出た...。Slackware-11.0にアップデートしたのはこの件に関しては意味無かったか。まぁ前のシステムはfsckかかりまくりだったので良い機会だったと納得しよう。
エラーメッセージに関しては2.4.37.1に固有の問題かもしれない。syslogのディスクアクセスは気になるところだが、それ以外は問題なさそうなので、ひとまず様子見としよう。
2009年06月18日 request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その6) [長年日記]
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その6)
request_module[net-pf-10]: waitpid(3788,...) failed, errno 1
の errno 1 は /usr/include/asm/errno.h より
#define EPERM 1 /* Operation not permitted */
を表していると思っていた。ところが /usr/src/linux/kernel/kmod.c より
178 int request_module(const char * module_name) 179 { 180 pid_t pid; 181 int waitpid_result; 182 sigset_t tmpsig; 183 int i; 184 static atomic_t kmod_concurrent = ATOMIC_INIT(0); 185 #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ 186 static int kmod_loop_msg; 187 188 /* Don't allow request_module() before the root fs is mounted! */ 189 if ( ! current->fs->root ) { 190 printk(KERN_ERR "request_module[%s]: Root fs not mounted\n", 191 module_name); 192 return -EPERM; 193 } 194 195 /* If modprobe needs a service that is in a module, we get a recursive 196 * loop. Limit the number of running kmod threads to max_threads/2 or 197 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method 198 * would be to run the parents of this process, counting how many times 199 * kmod was invoked. That would mean accessing the internals of the 200 * process tables to get the command line, proc_pid_cmdline is static 201 * and it is not worth changing the proc code just to handle this case. 202 * KAO. 203 */ 204 i = max_threads/2; 205 if (i > MAX_KMOD_CONCURRENT) 206 i = MAX_KMOD_CONCURRENT; 207 atomic_inc(&kmod_concurrent); 208 if (atomic_read(&kmod_concurrent) > i) { 209 if (kmod_loop_msg++ < 5) 210 printk(KERN_ERR 211 "kmod: runaway modprobe loop assumed and stopped\n"); 212 atomic_dec(&kmod_concurrent); 213 return -ENOMEM; 214 } 215 216 pid = kernel_thread(exec_modprobe, (void*) module_name, 0); 217 if (pid < 0) { 218 printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid); 219 atomic_dec(&kmod_concurrent); 220 return pid; 221 } 222 223 /* Block everything but SIGKILL/SIGSTOP */ 224 spin_lock_irq(¤t->sigmask_lock); 225 tmpsig = current->blocked; 226 siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP)); 227 recalc_sigpending(current); 228 spin_unlock_irq(¤t->sigmask_lock); 229 230 waitpid_result = waitpid(pid, NULL, __WCLONE); 231 atomic_dec(&kmod_concurrent); 232 233 /* Allow signals again.. */ 234 spin_lock_irq(¤t->sigmask_lock); 235 current->blocked = tmpsig; 236 recalc_sigpending(current); 237 spin_unlock_irq(¤t->sigmask_lock); 238 239 if (waitpid_result != pid) { 240 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n", 241 module_name, pid, -waitpid_result); 242 } 243 return 0; 244 }
240行〜241行が問題のエラーメッセージを出しているところなのだが、errnoに該当するのは -waitpid_result で、これは230行の waitpidのリターン値(-1)を符号反転したものに過ぎない。waitpidのリターン値が-1なのは単に「エラーで返ったよ」の印に過ぎず、真のエラーコードは errno に格納されているはず。なので、
239 if (waitpid_result != pid) { 240 #if 0 241 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n", 242 module_name, pid, -waitpid_result); 243 #else 244 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d realerrno %d\n", 245 module_name, pid, -waitpid_result, errno); 246 #endif 247 }
のようにして、カーネルをビルド中。
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その7)
本当の errno は
ECHILD 10 /* No child processes */
だった。
2.4系のスレッドの問題かもしれないが、はっきりとした事は言えない。とりあず
*** kernel/kmod.c.ORG 2009-06-18 01:09:00.000000000 +0900 --- kernel/kmod.c 2009-06-18 09:56:55.000000000 +0900 *************** *** 237,244 **** --- 237,251 ---- spin_unlock_irq(¤t->sigmask_lock); if (waitpid_result != pid) { + #if 0 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n", module_name, pid, -waitpid_result); + #else + if (errno != ECHILD){ + printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d realerrno %d\n", + module_name, pid, -waitpid_result, errno); + } + #endif } return 0; }
みたいにして、ECHILDの時はメッセージを出さないようにした。ビルド&再起動して様子をみているけれど、非常に場当たり的だが問題なさそう。
2009年06月19日 GARP(Gratuitous ARP) [長年日記]
_ GARP(Gratuitous ARP)
今日、初めて知った。自身のIPアドレス対応するMACアドレスを問い合わせるARPのことをGARP(Gratuitous ARP)というらしい。
自分に関する事を問い合わせるARPパケットに意味が有るのかと思うが、
- IPアドレスのダブリをチェックしたり(別の場所から自分自身が返事したら恐いわな)
- 他ノードの持つARPテーブル内の自身の情報を強制的に更新させる
という意味がある。
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その8)
カーネルソースの書き換え(kernel/kmod.c)により、無理矢理エラーメッセージを出なくして、強引に解決させたと思われた、この一件。実は以下のような状況が発生していた。
501 m-ito@lib100 /home/m-ito> ps ax|egrep defunct 1276 ? Z 0:00 [modprobe.old] <defunct> 1411 ? Z 0:00 [modprobe.old] <defunct> 13756 ? Z 0:00 [modprobe.old] <defunct> 13815 ? Z 0:00 [modprobe.old] <defunct> 7973 ? Z 0:00 [modprobe.old] <defunct> 14710 ? Z 0:00 [modprobe.old] <defunct> 15028 ? Z 0:00 [smtp_wrapper] <defunct> 15153 pts/3 S+ 0:00 egrep defunct 502 m-ito@lib100 /home/m-ito>
modprobe.oldがいわゆるゾンビプロセスになっている。つまり、正しくwaitpid()が機能していないという、あの状況にはっきりと呼応する。
503 m-ito@lib100 /home/m-ito> pstree -p|egrep modprobe.old |-named(7972)---modprobe.old(7973) |-ntpd(1409)---modprobe.old(1411) |-sshd(1274)-+-modprobe.old(1276) | |-sshd(13755)-+-modprobe.old(13756) | |-sshd(13814)-+-modprobe.old(13815) | `-sshd(14709)-+-modprobe.old(14710) 504 m-ito@lib100 /home/m-ito>
named, ntpd, sshd は /usr/local/ 配下にあるのだけれど、Slackware-10.1から11.0にアップデートしたときには、リコンパイルせずに、既存の /usr/local/ をそのまま引き継いだ。
それが原因かと考え、とりあえずnamedをリコンパイルしてみたけれど、状況は変わらなかった。
心配の種は尽きまじ...
_ ruby(1.8.x)儂(わし)的解釈によるメモ(OSコマンドインジェクション対策)
シェルに渡す(外部から入力された)パラメータに関して、特殊文字とか、ややこしいことは考えずに全ての文字に対して、1文字ずつエスケープを行う。
#! /usr/bin/ruby input = "test5.rb';`echo CRACKED`; echo '\\" input.gsub!(/(.)/){'\\' + $1} command = "echo #{input}" p command system(command)
"echo \\t\\e\\s\\t\\5\\.\\r\\b\\'\\;\\`\\e\\c\\h\\o\\ \\C\\R\\A\\C\\K\\E\\D\\`\\;\\ \\e\\c\\h\\o\\ \\'\\\\" test5.rb';`echo CRACKED`; echo '\
これで良くないだろうか?
2009年06月23日 Unable to handle kernel paging request at virtual address ... etc [長年日記]
_ Unable to handle kernel paging request at virtual address ... etc
lib100サーバにまたヤバゲなメッセージが残されている。
Jun 22 17:16:59 lib100 kernel: Unable to handle kernel paging request at virtual address 655f22b7 Jun 22 17:16:59 lib100 kernel: printing eip: Jun 22 17:16:59 lib100 kernel: c0142200 Jun 22 17:16:59 lib100 kernel: *pde = 00000000 Jun 22 17:16:59 lib100 kernel: Oops: 0000 Jun 22 17:16:59 lib100 kernel: CPU: 0 Jun 22 17:16:59 lib100 kernel: EIP: 0010:[<c0142200>] Not tainted Jun 22 17:16:59 lib100 kernel: EFLAGS: 00210246 Jun 22 17:16:59 lib100 kernel: eax: 655f228b ebx: c3ffec20 ecx: 00008000 edx: 00000000 Jun 22 17:16:59 lib100 kernel: esi: ffffffe2 edi: 00008001 ebp: c158df84 esp: c158df50 Jun 22 17:16:59 lib100 kernel: ds: 0018 es: 0018 ss: 0018 Jun 22 17:16:59 lib100 kernel: Process ruby (pid: 21691, stackpage=c158d000) Jun 22 17:16:59 lib100 kernel: Stack: 00000000 00000000 00000004 c04e3ca0 00008000 c198e000 400d23e0 bffee0ac Jun 22 17:16:59 lib100 kernel: c0136ebe c198e000 00008001 000001b6 c158df84 c04e3ca0 c10c52e0 400d23e0 Jun 22 17:16:59 lib100 kernel: c0140b0a 00000006 00000001 00000001 00000006 00000006 c013725b c198e000 Jun 22 17:16:59 lib100 kernel: Call Trace: [<c0136ebe>] [<c0140b0a>] [<c013725b>] [<c0108963>] Jun 22 17:16:59 lib100 kernel: Jun 22 17:16:59 lib100 kernel: Code: f6 40 2c 01 0f 84 ec fc ff ff f7 c7 02 00 00 00 0f 84 e0 fc
メモリーの障害か、swapエリアのI/O error辺りか...と思い、予備のメモリと交換して、mkswap -c /dev/hda?でもするかと考えてた矢先に、このtDiaryが...
Plugin Error Errors in plugins? Retry to Update or Configure. TDiary::PluginError Plugin error in '50sp.rb'. Plugin error in 'misc/plugin/amazon.rb'. Input/output error - /usr/lib/ruby/1.8/rexml/xpath_parser.rb (plugin/50sp.rb):129:in `load_plugin'
みたいなエラーを表示して動かなくなっていた。 /usr/lib/ruby/1.8/rexml/xpath_parser.rb を cat で表示させると
cat: /usr/lib/ruby/1.8/rexml/xpath_parser.rb: Input/output error
確かにI/O error状態で、さらに
# ls -al /usr/lib/ruby/1.8/rexml/xpath_parser.rb -rw-r--r-- 1 root root 3364114146225291585 1993-12-03 08:59 /usr/lib/ruby/1.8/rexml/xpath_parser.rb
と、脅威のファイルサイズを表示してくれた。ファイルの中身を確認すると、末尾に延々と NULL がくっついている感じ。
mv xpath_parser.rb xpath_parser.rb.ORG cat xpath_parser.rb.ORG >xpath_parser.rb
catではきっちり32KByte読み出したところで I/O Error発生。
vi xpath_parser.rb
にて xpath_parser.rb のおケツにくっついた NULL を削除したら tDiary は復活した。後は、 fsck をかけて、超巨大な xpath_parser.rb.ORG がどうなるかだな。
それと、気になるのは
Unable to handle kernel paging request at virtual address
と
-rw-r--r-- 1 root root 3364114146225291585 1993-12-03 08:59 /usr/lib/ruby/1.8/rexml/xpath_parser.rb
の関係。鶏が先か、卵が先なのか...。
_ Unable to handle kernel paging request at virtual address ... etc(2)
fsckをかけてみると、やはりボコボコと修復されていった。そして、超巨大ファイルもグッとシュリンクされていた。少しは末尾に NULL が残っていたが。
不安は山盛りだがとりあえずこの状態で様子を見てみる。
2009年06月28日 Libretto U100/190DSB [長年日記]
_ Libretto U100/190DSB and Slackware-12.2
lib100(myh.no-ip.org)サーバの方は、超巨大ファイルをfsckにて消しさってからは、すこぶる調子がよろしい。
さて、家ではlib100サーバの予備機を24時間365日起動のfirefox専用端末として利用してきたのだけれど、さすがにクライアントとして動かすにはキツイと感じ始めた。
そこで、今流行のNetBookとやらをヤフオクで調査してみた。とりあえず東芝からはNB100という機種が出ているよう。値段的には4万円前後というところ。またどうでもいいことだが、型番に100が付くという所に親近感をおぼえる。
そんなことで、かなりNB100に気持が傾いていたのだが、たまたまLibretto U100という機種も何台かオークションに出品されていた。もちろんLibrettoシリーズ最後(?)の機種(でかつ型番に100が付く!)という事は知っていたし、発売当時(2005年ごろ)、20万円程度していて、とても手が出なかったという記憶があるのだが、この機種も3〜4万円程度で落札されている。
とはいえ4年程昔の機種なので、最新のNB100と比べれば見劣りするかと思ったのだが、DVD-RWに対応したドライブも付属しているし、CPUの性能もNB100のatom(1.6GHz)に対してU100のpentium-M(1.1GHz)は、互格らしい(atom 1.6GHzはCeleron 800〜900MHz程度)。もちろん消費電力では圧倒的にatomの方が有利なのだが、全体の消費電力に占める割合はハードディスクや液晶のバックライトの占める割合の方が大きいので、あまり差がでない。まして、自分的な使い方としては、あくまで24時間起動の自宅firefox端末なので、バッテリーの持ちはあまり気にする必要が無い。
それと、何も考えずにブートデバイスとして利用できる光学ドライブが付属するという点は、Linuxをインストールする上で非常にやりやすい。この点はLibretto100で苦労した事から考えると非常に魅力的だ。そういう周辺機器の点で、NB100はNetBookという性格上どうしても切り捨てざるをえない。
...というような事を総合的に判断し U100落札しちゃいました。結局4万円をちょっと越えました(^^;。
_ 再パーティショニング
さて、落札後の取り引きもスムーズに進み、入金の翌日にブツは到着。しばらくプレインストールのMS-Windows XPをいじってみるも、迷子になったような気分に襲われ、やっぱりLinux(Slackware-12.2)を入れる。ただし、今回は家族も使うので、プレインストールのMS-Windows XPも残して、デュアルブートにしようと思う。
ともかく作業を始める前に「困ったときは Q&A」の「P.48 4 システム復元ツールのバックアップをとる」に従いシステムリカバリDVDとクイックプレイリカバリCDを作成した。その後、「P.83 2 ハードディスクから復元する」に従ってXPのパーティションを縮小して再インストールするのだが、その前にSlackware-12.2のインストールCDで起動してパーティションを切り直しておく。
切り直す前
Disk /dev/hda: 59.8 GB, 59814236160 bytes 255 heads, 63 sectors/track, 7272 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0xe2d9e2d9 Device Boot Start End Blocks Id System /dev/hda1 * 1 6882 55279633 7 HPFS/NTFS /dev/hda2 6883 7271 3124642+ 1c Hidden W95 FAT32 (LBA)
切り直した後
Disk /dev/hda: 59.8 GB, 59814236160 bytes 255 heads, 63 sectors/track, 7272 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0xe2d9e2d9 Device Boot Start End Blocks Id System /dev/hda1 * 1 3395 27270306 7 HPFS/NTFS /dev/hda2 3396 3520 1004062+ 82 Linux swap /dev/hda3 3521 6882 27005265 83 Linux /dev/hda4 6883 7271 3124642+ 1c Hidden W95 FAT32 (LBA)
元々の/dev/hda2がリカバリ領域なので、それを間違わずに/dev/hda4に再割り当てすること。その後、0(ゼロ)キーを押しながら電源を投入し復元システムが起動したら、「2 パーティションサイズを変更せずに復元」を実行する。
_ Slackware-12.2のインストール
インストールそのものは何も問題ない。普通のノートパソコンと何も変わらない。光学ドライブのありがたみがしみる。
ここからは、細かい部分でのポイントを少し...
_ 内蔵無線LAN(ath5k Atheros AR2414)の設定
最初、/etc/rc.d/rc.wireless.confの方を有効にして設定していたのだが、インタフェース(wlan0)を認識し、自分自身にはpingが飛ぶものの、外部には継らない状況だった。結局、/etc/rc.d/rc.wireless.confの方は触る必要は無く(有効にする必要すら無い)、/etc/rc.d/rc.inet1.confの方に
## Config information for wlan0: IFNAME[4]="wlan0" IPADDR[4]="192.168.0.190" NETMASK[4]="255.255.255.0" USE_DHCP[4]="" WLAN_ESSID[4]=xxxxxxxxxxx <- 伏せ字 WLAN_KEY[4]="xxxxxxxxxx" <- 伏せ字 TEWAY="192.168.0.100"
の様に記述するだけでネットワークに接続できた。
_ xorg (X Window System)
標準でインストールされている /etc/X11/xorg.conf のModesに"1280x768"を追加するだけでもとりあえずは問題ない。ただしドライバはvesaを利用するので、多少速度の面で不満がある。
Libretto U100 xorg.confで検索すると専用ドライバ(i810)を利用した例がいくつも出て来る。これらをそのまま利用させていただいても良い。ただし、これらの例では SWCursor が有効になっているパターンが多く、その為DRI(Direct Rendering Infrastructure)が有効に出来ない点に注意が必要。おそらくこれらの報告がなされた時点のXでは、この指定が無ければマウスカーソルが正しく表示出来なかったのだろうが、Slackware-12.2のXは
X.Org X Server 1.4.2 Release Date: 11 June 2008 X Protocol Version 11, Revision 0
とのことで、SWCursorの指定は必要無いようだ。
結局、私は xorgsetupでは画面がブラックアウトしてしまうので、xorgconfigを利用してベースを作り、Libretto U100 xorg.confで検索されるページから
Modeline "1280x768" 90 1280 1328 1552 1704 768 768 788 808 +hsync +vsync
の指定を拝借して設定した。結果としては DRI(Direct Rendering Infrastructure)も有効になり、xengineで8800rpm程度は出ている。