質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

3回答

2477閲覧

write() の書き込みが失敗する状況の作り方について

yoshiki_iwasa

総合スコア23

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

1クリップ

投稿2021/04/04 03:19

write(int fd, void *ptr, size_t count)関数の実行時、count 未満の書き込みをfdに行う方法ってありますか??

現在、write()を使ったプログラムを書いてまして。その過程で、「書き込みは成功するけど、第三引数byte未満の書き込みしかできなかった」という状況のエラー処理をテストする方法がわからなくて困っております。

以下のコードのコメント部分をテストする方法がわかりません。

C++

1#include <iostream> 2#include <unistd.h> 3#include <fcntl.h> 4 5int main() 6{ 7 int fd = open("testFile", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU); 8 char *ptr = "0123456789"; 9 10 int ret = write(fd, ptr, 10); 11 if (ret == -1) 12 { 13 std::cout << "書き込み失敗" << std::endl; 14 } 15 else if (ret < 10) 16 { 17     //ここに入るパターンをテストできない(T T) 18 std::cout << "書き込み不足" << std::endl; 19 } 20 else 21 { 22 std::cout << "書き込み成功" << std::endl; 23 } 24}

man page を見ると、

書き込まれるバイト数は count よりも小さくなることがある。 例えば、書き込み対象の物理メディアに十分な領域がない場合、 リソース上限 RLIMIT_FSIZE に達した場合 (setrlimit(2) 参照)、 count バイト未満の書き込みが行われた後で 呼び出しがシグナルハンドラーにより割り込まれた場合、 などである。

とあるんですが、「これって再現するのめちゃむずくない...」 となっています。
うまくwirte をテストする方法などありませんか?

自分で考えたこと

open() でファイルの書き込み可能最大数を指定してファイルをopenまたはcreateできれば、writeの実験できるなぁと思いましたが、その方法もわからず…

力を貸してください!!!!!1

yohhoy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

write を乗っ取るという方法が考えられます。

テストしたいのは write を使う側であって write が本当の意味で失敗するかどうかは重要ではありませんから、適当にマクロで write を別のものに差し替えればよいでしょう。 Linux なら LD_PRELOAD を設定することで実行時に差し替えることも出来ます。

投稿2021/04/04 06:41

SaitoAtsushi

総合スコア5466

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikapy

2021/04/04 09:19

上司が納得するかどうかでしょうね。多分、納得しないでせう。 自分としては、考えられるケースのすべてでテストすべきだと思いますけど。 例:はやぶさ2
sigsegv

2021/04/04 12:52

納得しないのはなぜ?単体テストなら妥当な方法では?
guest

0

投稿2021/04/04 05:23

hoshi-takanori

総合スコア7895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoshiki_iwasa

2021/04/04 05:27

回答ありがとうございます! そんな方法が… ちょっとやってみますね!
guest

0

RLIMIT_FSIZEを設定することで再現できそうですね。

https://linuxjm.osdn.jp/html/LDP_man-pages/man2/write.2.html

書き込まれるバイト数は count よりも小さくなることがある。 例えば、書き込み対象の物理メディアに十分な領域がない場合、 リソース上限 RLIMIT_FSIZE に達した場合 (setrlimit(2) 参照)、 count バイト未満の書き込みが行われた後で 呼び出しがシグナルハンドラーにより割り込まれた場合、 などである。 (pipe(7) も参照のこと。)

c++

1#include <iostream> 2#include <unistd.h> 3#include <fcntl.h> 4#include <sys/time.h> 5#include <sys/resource.h> 6 7int main() 8{ 9 rlimit limit; 10 limit.rlim_cur = 5; 11 setrlimit(RLIMIT_FSIZE, &limit); 12 13 int fd = open("testFile", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU); 14 char *ptr = "0123456789"; 15 16 int ret = write(fd, ptr, 10); 17 if (ret == -1) 18 { 19 std::cout << "書き込み失敗" << std::endl; 20 } 21 else if (ret < 10) 22 { 23 //ここに入るパターンをテストできない(T T) 24 std::cout << "書き込み不足" << std::endl; 25 } 26 else 27 { 28 std::cout << "書き込み成功" << std::endl; 29 } 30}

bash

1$ g++ main.cc && ./a.out 2main.cc: 関数 ‘int main()’ 内: 3main.cc:14:17: 警告: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 4 14 | char *ptr = "0123456789"; 5 | ^~~~~~~~~~~~ 6書き込み不足

投稿2021/04/04 09:35

yskszk63

総合スコア161

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2021/04/04 10:00

setrlimitで設定するrlimit構造体ですが、確実な動作の為、メンバー変数rlim_curへも値をセットしておいた方が良いかと思います。 https://linuxjm.osdn.jp/html/LDP_man-pages/man2/getrlimit.2.html > ソフトリミットは、カーネルが対応するリソースに対して課す制限値である。 ハードリミットはソフトリミットの上限として働く。 特権を持たないプロセスは、ソフトリミットの値を 0 からハードリミットの範囲に設定することと、...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問