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

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

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

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

Q&A

解決済

3回答

3733閲覧

gccでシステムコールを含むコードのコンパイル

cingyan

総合スコア29

C

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

0グッド

0クリップ

投稿2016/10/07 05:19

編集2016/10/10 06:12

C言語によるプログラミング応用編という本でプログラミングの勉強をしています。

本から引用

ネットワーク越しにデータのやり取りを行う場合に用いるBerkley Socketは、標準入出力関数が利用するストリームポインタではなくディスクリプタをを用いたものとなっています。

このようにいきなりディスクリプタという言葉が出てきて意味をネットで調べましたが、分かりませんでした。
その意味を教えてください。

それと、システムコールを用いてストップウォッチを作るサンプルプログラムが載っていて、それを入力しgccでコンパイルしましたが、できませんでした。
gcc version 5.2.1 20151010

gcc -v と打つと
省略
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.2.1-22ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
省略

POSIXと記録されているので、gccでもシステムコールの関数が使えると思うのですが、やり方を教えてください。
それともgccではできないのでしょうか。
Ubuntu 15.10を使用しています。
よろしくお願いします。

追記 : 16/10/10
教えて頂いた通りに修正しましたがまだ、コンパイルができず、実行ファイルができません。
修正したコードと実行結果を載せますのでよろしくお願いします。

07_01.c

#include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include <sys/time.h> #define DATA_FILENAME "./stopwatch.dat" int iniTime(struct timeval *startTime) { int fd,ret=0; gettimeofday(startTime,NULL); if((fd=open(DATA_FILENAME,O_WRONLY|O_CREAT|O_TRUNC,0644))<0) return -1; if(write(fd,startTime,sizeof(*startTime))!=sizeof(*startTime)) ret=-1; close(fd); return ret; }

07_02.c

#include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <fcntl.h> #include <signal.h> #define DATA_FILENAME "./stopwatch.dat" int restoreTime(struct timeval *startTime) { int fd,ret=0; if((fd=open(DATA_FILENAME,O_RDONLY))<0) return -1; if(read(fd,startTime,sizeof(*startTime))!=sizeof(*startTime)) ret =-1; close(fd); return ret; }

07_04.c

#include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <fcntl.h> #include <signal.h> int restoreTime(struct timeval *startTime); void printDiff(struct timeval *t1,struct timeval *t2); void lastTime(int unused) { struct timeval startTime,lastTime; if(restoreTime(&startTime)<0) exit(EXIT_FAILURE); gettimeofday(&lastTime,NULL); printDiff(&lastTime,&startTime); exit(EXIT_SUCCESS); }

07_05.c

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <fcntl.h> #include <signal.h> void printDiff(struct timeval *t1,struct timeval *t2) { struct timeval diff; timersub(t1,t2,&diff); printf("%02lu:%2lu.%02lu\n", diff.tv_sec/60, diff.tv_sec%60, diff.tv_usec/10000); }

main.c

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <fcntl.h> #include <signal.h> int initTime(struct timeval *startTime); int restoreTime(struct timeval *startTime); void lastTime(int unused); void printDiff(struct timeval *t1,struct timeval *t2); int main(int argc,char *argv[]) { int c; struct timeval startTime={0,0},currentTime; while((c=getopt(argc,argv,"cs"))!=EOF) { switch(c) { case 's': if(initTime(&startTime)<0) { fprintf(stderr,"開始時刻の初期化、書き込みに失敗\n"); exit(EXIT_FAILURE); } break; case 'c': if(restoreTime(&startTime)<0) { fprintf(stderr,"開始時刻の読み込みに失敗\n"); exit(EXIT_FAILURE); } break; } } if(startTime.tv_sec==0||argc!=2) { fprintf(stderr,"-sまたは-cオプションを指定してください。\n"); exit(EXIT_FAILURE); } signal(SIGINT,lastTime); while(1) { sleep(1); gettimeofday(&currentTime,NULL); printDiff(&currentTime,&startTime); } exit(EXIT_SUCCESS); }

ターミナルでコンパイルすると、

$ gcc 07_01.c 07_02.c 07_04.c 07_05.c main.c /tmp/cc8inniA.o: 関数 `main' 内: main.c:(.text+0x4a): `initTime' に対する定義されていない参照です collect2: error: ld returned 1 exit status $

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

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

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

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

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

mit0223

2016/10/08 12:12

07_01.c の Write は write の間違えではありませんか?
guest

回答3

0

リンクできないのは 07_01.c での関数の名前が iniTime になっているからでは?
t が抜けているように思います。

投稿2016/10/10 06:38

Eki

総合スコア429

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

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

cingyan

2016/10/11 04:45

ご回答、ありがとうございました。 仰る通り、抜けていました。 お恥ずかしい。
guest

0

ベストアンサー

ディスクリプタという言葉が出てきて意味をネットで調べましたが、分かりませんでした。

その意味を教えてください。

普通はファイルディスクリプタといいます。「ファイルディスクリプタ」で調べていただければ、いろいろ見つかると思います。ファイルとは関係のないネットワークのソケットを開いても「ファイルディスクリプタ」が返されます。
これが Unix の大発明と言われており、世界で最初に多様性を得た仕組みです。相手がファイルなのか、ネットワークなのかデバイスなのかに関係なく、 open, read, write, close というシステムコールが使えます。

POSIXと記録されているので、gccでもシステムコールの関数が使えると思うのですが、やり方を教えてください。

  • このPOSIXはスレッドの互換性のオプションでおそらく無関係です
  • Ubunts であれば、教科書にあるようなプログラムはだいたい動作するはずですが、教科書は Windows むけなのでしょうか?
  • プログラムのソースコードとエラーメッセージをいただかないと質問に答えられません

ソースコードとエラーメッセジを見ましたが、main.c 以外は利用するライブラリに対する #include が宣言されておらず、当然エラーになります。教科書では、そこを省略しているのではないでしょうか? C言語の場合、どんな簡単な例でも#include <stdio.h> くらいは必ず必要になります。

一度、すべてのソースファイルに main.c と同じように以下の #include を指定してみてください。

C

1#include <stdlib.h> 2#include <unistd.h> 3#include <sys/time.h> 4#include <fcntl.h> 5#include <signal.h>

投稿2016/10/07 09:27

編集2016/10/08 16:30
mit0223

総合スコア3401

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

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

cingyan

2016/10/08 03:21

ご回答、ありがとうございました。 本の、この章では、POSIX互換のOSの上でプログラミングを行う場合のみです。と書いてあります。 それでは、コードとgccを行った結果を後ほど追記します。
guest

0

「ディスクリプター」は、OS内でソケットやファイルなどの資源を管理するための「番号」です。0以上の値が振られます(socket()関数のmanページ)。日本語に訳して「記述子」とも呼びます。

システムコールを用いてストップウォッチを作るサンプルプログラム

最低限、「どのようなプログラム」を書いて「どんなエラーが出た」のかは示してください。エスパーでもない限り、情報が少なすぎてコメント不能です。

投稿2016/10/07 05:33

maisumakun

総合スコア145121

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

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

cingyan

2016/10/08 03:07

ご回答、ありがとうございました。 ディスクリプタについてイメージができました。 ソースコードを載せなかったのは、コンパイルできなかったので、記述したソースファイルが正しいのか分からなかったので、公表を控えたのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問