Systemcall readv()

Hallo an alle.

Im Rahmen einer Übung versuche ich einen readv() Unix/Linux-Systemcall in einem C-Programm abzusetzen. Folgender Code:

**#include „stdio.h“
#include „sys/types.h“
#include „sys/stat.h“
#include „sys/uio.h“
#include „fcntl.h“
#include „string.h“

int main(){
struct iovec iov[2];
int nr, fd, i;

char *buff[2];
fd=open(„ler.txt“,O_RDONLY);

for(i=0;i

Der readv() Aufruf meldet „-1“ zurück. Scheitert also. Ich verstehe den Grund nicht.
Wenn mein Verständniss für diesen Systemcall richtig ist, dann muss ein Vector spezifiziert werden. Das tue ich in der FOR-Schleife.

Der funktionierende writev() Aufruf sieht so aus:

int main(){
struct iovec iov[5];
int nr, fd, i;

char* buf[]={
„There was a young lady named Bright\n“,
„Her speed was faster than light\n“,
„She went out one day\n“,
„In a relative way\n“,
„And returned the previous night\n“};

fd=open(„rel.txt“,O_WRONLY|O_CREAT|O_TRUNC,0644);

for(i=0;i

Bin für jede Hilfe dankbar!**

Hallo Vitali,
der Fehler liegt wahrscheinlich nicht am Code. Ich habe dein Beispiel nur etwas um eine Statusmeldung erweitert, ohne was am Inhalt zu ändern (die Zusätze fett hervorgehoben), und bei mir funktioniert es:

#include "stdio.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/uio.h"
#include "fcntl.h"
#include "string.h"
**#include "errno.h"**

int main(){
 struct iovec iov[2];
 int nr, fd, i;
 char \*buff[2];

fd=open("ler.txt",O\_RDONLY);

for(i=0;iprintf("Meldung: %s\n",strerror(errno));
close(fd);
printf("%d Bytes gelesen\n",nr);
}

Das übersetzt und gestartet liefert mit folgende Ausgabe:

Meldung: Success
4 Bytes gelesen

Viele Grüße
Marvin

Marvin, tatsächlich. Ursprünglich hatte ich es auf einem Knoppix 6.2.x von CD probiert. Nach Deiner Antwort habe ich es auf Knoppix 6.3.4 probiert- auch ohne Erfolg. Heute auf einem Ubuntu Linux 11.4 von CD- hier erhalte ich die von Dir gepostete Ausgabe. Der Systemaufruf funktiert also.

Ich bin damit einen Schritt weiter, aber es funktioniert noch nicht wie ich mir das vorgestelt hatte.
Ich habe den Code noch etwas mit Bemerkungen erweitert:

#include „stdio.h“
#include „sys/types.h“
#include „sys/stat.h“
#include „sys/uio.h“
#include „fcntl.h“
#include „string.h“

int main(){
struct iovec iov[2];
int nr, fd, i;

char *buff[2];
fd=open(„ler.txt“,O_RDONLY);
printf(„File descriptor Nr.: %i\n“, fd);

for(i=0;i
In der ler.txt steht folgendes:

hhh
vvv

Ich stelle es mir wie folgt vor. Vielleicht könnt ihr es prüfen und mich korrigieren.

  1. Das struct iov ist angelegt für 2 Blöcke/Segmente mit der Größe 4 Bytes.
  2. Im iov_base sind die Adressen der Puffer buff[0] und buff[1] gespeichert in die hinein gelesen wird.
  3. Die beiden Zeilen der ler.txt sind mit dem Zeilenumbruch genau 4 Bytes groß und sollten in die einzelnen Puffer passen
  4. readv() liest (wie das struct iov vorgibt) 4 Bytes und legt sie auf die Adresse des buff[0] und weitere 4 Bytes auf die Adresse des buff[1]

Die Ausgabe des Programms sieht allerdings so aus:

File descriptor Nr.: 3
Mit readv() gelesen: 4 Bytes
Inhalt buff[0]: hhh
7n
Inhalt buff[1]: ��[]��

Was ist hier los?

Hallo Vitali,

aber es funktioniert noch
nicht wie ich mir das vorgestelt hatte.

Ich habe es auch ausprobiert und mit diesem Code funktioniert es (Fehlerüberprüfungen habe ich jetzt einfach mal weggelassen):

int main()
{
#include 
#include 
#include 
#include 

char foo[4], bar[4];
struct iovec iov[2];
int nr, fd, i;

fd = open ("ler.txt", O\_RDONLY);

iov[0].iov\_base = foo;
iov[0].iov\_len = sizeof(foo);
iov[1].iov\_base = bar;
iov[1].iov\_len = sizeof(bar);

nr = readv (fd, iov, 2);
printf ("%d Bytes gelesen\n", nr);
close (fd);

for (i = 0; i 
Das produziert folgende Ausgabe:


    8 Bytes gelesen
    FELD 0: hhh
    FELD 1: vvv
    Feld foo: hhh
    Feld bar: vvv


Daß es die zwei Strings foo und bar zweimal ausgibt habe ich lediglich aus Testgründen eingebaut. Eigentlich reicht entweder die for-Schleife mit iov[i].iov\_base oder die zwei printf.
Soweit, so schlecht. Ich habe leider auch nicht verstanden, warum es nicht funktioniert, wenn man die Strings nicht einzeln nimmt, sondern in ein Array packt, so wie Du es möchtest.
Leider habe ich auch kein Beispiel gefunden, das es auf deine Weise macht. in den wenigen Beispielen passiert es immer als Einzelaufruf von iov[0], iov[1] usw., z.B. hier:
[http://pubs.opengroup.org/onlinepubs/009695399/funct...](http://pubs.opengroup.org/onlinepubs/009695399/functions/readv.html)
Mit meinen eingerosteten C-Kenntnissen komme ich da auch nicht weiter. Ich schlage dir vor, das Problem nochmal im C-Brett zu stellen, wenn sich hier nicht noch jemand meldet. Es handelt sich zwar um Linux-Systemaufrufe, aber letztendlich um C und Pointer, Arrays von Strings u.ä. Die C-Spezialisten dort haben vielleicht eine Idee, woran es liegt.

Viele Grüße
Marvin

Abschluss: Systemcall readv()
So, dass Problem ist nicht der readv() Systemaufruf, sondern rein programmiertechnischer Natur.
Ihr könnt es im C/C++ Baum weiter verfolgen:
http://www.wer-weiss-was.de/app/service/board_navi?A…