Sida 1 av 1
Skulle behöva lite C hjälp?
Postat: 04 sep 2007, 23:58
av lennart
Jag har fått en liten skol uppgift att skriva ett c-program som skall göra ett system call (sys_stat) via en funktion som finns i en färdig kompilerad fil. Sys_stat har två argument, char * och struct __old_kernel_stat *, där första argumentet skall vara ett argument ifrån terminalen. Ett av problemen jag har är att få till struct:en, jag bifogar koden jag har skrivit.
Kod: Markera allt
#include <stdio.h>
#include <string.h>
struct stat {
};
extern statPrint(char*, struct stat*);
int main(int argc, char *argv[])
{
int n;
struct stat *stat;
/* call statPrint in the libstat.o file */
n = statPrint(argv[1],stat);
return 0;
}
Dessutom får jag problem när jag skall länka ihop filerna med kommandot: gcc -o stat stat.o libstat.o får då följande felmedelande: libstat.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
Alla filer ligger i samma katalog, men har egentligen ingen aning hur dom skall ligga och jag utgår ifrån att filen är korrekt.
Hoppas någon vänlig kan hjälpa mig med detta?
SV: Skulle behöva lite C hjälp?
Postat: 05 sep 2007, 00:08
av gasol
testa å kompilera så här:
om filen heter stat.c
Annars så kan du ju testa med detta också
btw är libstat.o kompilerat på en linux-dator eller är det en solaris / BSD binär ?
Sedan så måste du allokera minne för din stat struct eller så har du den på stacken, annars så kommer det bli fel när funktionen försöker läsa den adressen.
edit: eventuellt så kanske det är så att filen är kompilerad till en vanlig x86 processor och du kör en 64-bitars installation?
SV: Skulle behöva lite C hjälp?
Postat: 05 sep 2007, 00:51
av lennart
Inget av kommandona funkar. Jag kör en x86:a och jag vet inte om libstat.o är kompilerat på linux eller solaris/bsd, jag visste inte att det var skillnad på dessa binärer, får försöka fråga nästa gång jag får tag på läraren. Skulle dock fortfarande behöva lite hjälp hur man gör med structen, då jag inte är så hemma på språket C. Eller alternativt om någon skulle vilja visa hur man gör ett syscall med stat utan att använda sig av den förkompilerade filen?
SV: Skulle behöva lite C hjälp?
Postat: 05 sep 2007, 11:24
av gasol
En struct är egentligen en samling av variabler av olika eller samma typ.
Kod: Markera allt
struct namn {
typ1 namn1;
typ2 namn2;
/* osv... */
};
/* t.ex så skulle du kunna representera en 3d - vektor som en struct */
struct vector3d {
float x;
float y;
float z;
};
/* eller på ett mer kompakt sätt */
struct vector3d {
float x, y, z;
}
/* Sedan för att komma åt / tilldela ett värde i en struct så gör du såhär: */
/* om man har en pekare till en struct så accessar du värden med -> istället för . */
#define POW2(x) ((x) * (x))
#include <math.h>
int get_length(struct vectord3d *vect) {
return sqrtf(POW2(vect->x) + POW2(vect->y) + POW2(vect->));
}
int main() {
struct vector3d vect; /* deklaration */
int length;
/* då structen är på stacken så använder du . */
vect.x = 45.0;
vect.y = 25.0;
vect.z = 0.0;
length = get_length(&vect); /* & tecknet gör att du skickar med adressen till structen */
return length;
}
edit: har inte kompilerat och testat den här koden jag skrev, så det är möjligt att det finns fel här.
SV: Skulle behöva lite C hjälp?
Postat: 05 sep 2007, 12:38
av Lars
Du måste på något sätt veta hur structen ser ut, jag är osäker på om den informationen finns o objekt-filen. Har du ingen ytterligare information?
För att kolla objektfilen så kan du använda kommandot file:
Kod: Markera allt
jag@dator:~$ file libstat.o
libstat.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.0, not stripped
SV: Skulle behöva lite C hjälp?
Postat: 05 sep 2007, 14:01
av gasol
Den informationen finns inte kvar i o-filen, adresseringen i en struct är bara offset (ev med padding) från pekaren som beräknas vid kompilering.
Men det borde väl stå i specen till uppgiften
SV: Skulle behöva lite C hjälp?
Postat: 05 sep 2007, 23:13
av lennart
Meningen med uppgiften är att man skall lära sig lite om system anrop, därav anledningen till att man får en .o fil, för att man i nästa uppgift skall skriva allt själv. Kan bifoga hur resultatet skall se ut. Har även fått bekräftat att .o filen är kompilerad på en SPARC, då dom inte har linuxburkar på skolan, har bett om en fil till linux. Nedan följer resultatet av en körning.
Kod: Markera allt
[joga@shell ~] $ ./stat /etc/passwd
File: '/etc/passwd'
Size: 663271 Blocks: 1312 IO Block: 8192
Device: 0x01540000h Inode: 24124 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 1/ other)
Access: 2005-11-09 09:17:46 (2005-11-09 08:17:46 UTC)
Modify: 2005-11-09 09:17:01 (2005-11-09 08:17:01 UTC)
Change: 2005-11-09 09:17:01 (2005-11-09 08:17:01 UTC)
Har börjat skriva på andra uppgiften, eftersom jag inte kunde göra den första, skulle dock behöva lite hjälp med den. Det gäller datumen i ovanstående körning, dom returneras i structen som antal sekunder efter midnatt 1970. Jag undrar om det finns någon färdig funktion där man kan mata in antal sekunder och få tillbaks korrekt datum i en sträng eller olika heltalsvariabler eller liknande. Hoppas det inte blev för virrigt nu!
SV: Skulle behöva lite C hjälp?
Postat: 06 sep 2007, 06:59
av gasol
Kolla på funktionerna ctime(), asctime() samt även mktime() testa
För att få upp manualen.
SV: Skulle behöva lite C hjälp?
Postat: 06 sep 2007, 08:29
av Lars
Du kanske också ska köra "man 3 stat" och kika i /usr/include/bits/stat.h efter en struct stat, om det kanske är det du är ute efter.
SV: Skulle behöva lite C hjälp?
Postat: 10 sep 2007, 17:07
av fyxim
Känns som någon läser samma kurs.
Kod: Markera allt
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
extern statPrint(char*, struct stat*);
int main(int argc, char *argv[])
{
struct stat buffert;
stat(argv[1],&buffert);
statPrint(argv[1],&buffert);
}