Omtentamen Systemprogrammering, 5p 9 April 1994

· Skrivtid 9- 15
· Hjälpmedel: Kelley and Pohl. A Book on C.
· Maxpoäng 54 p (för godkänt krävs 34 p)
· Uppgifterna är slumpmässigt ordnade
· Om någonting är oklart, gör en tolkning och anteckna den.

Uppgift 1 (14 p)

För varje uppgift i denna tentamen.
a) Börja uppgiften på ett nytt blad och skriv namn och uppgiftsnummer längst upp till höger på bladet.
b) Använd endast en sida på varje blad.

Uppgift 2 (4 p)

I UNIX finns det olika sorters kommandon. Beskriv skillnaderna mellan
a) Inbyggda kommandon
b) Aliases
c) Externa kommandon
d) Egna kommandon

Uppgift 3 (4)

Skriv så säkra macron som möjligt som plockar ut en bit från en integer:
a) BIT0(x) returnerar den minst signifikanta biten ("högraste'').
b) BIT(x,n) returnerar den n:te biten (räkna den minst signifikanta biten som 0).
c) Förutsatt att man använder heltalsuttryck, kan användandet av macrona ovan resultera i oväntande/oönskade resultat? Motivera ditt svar.

Uppgift 4 (12 p)

Skriv en C-funktion getopt. Funktionen ska plocka ut optioner till ett C-program. getopt ska anropas med argc, argv och en sträng, optstring, som argument. Funktionen ska gå igenom argv och leta efter de optioner som finns beskrivna i optstring.
För varje anrop ska den returnera nästa optionstecken i argumentlistan och returnera -1 när alla argument gåtts igenom.
optstring ska innehålla de tecken som kan användas som optionstecken. Man ska kunna ange att optioner har argument genom att sätta ett kolon efter optionsbokstaven i optstring.
Två externa variabler optarg och optind ska användas för att returnera mer information från getopt. För varje option som har ett argument ska optarg peka på argumentet till optionen. Efter att alla optioner har gåtts igenom ska optind vara index i argv till det första argumen- tet efter optionerna. getopt ska returnera tecknet '?' om den hittar en option som inte finns med i optstr eller om en option som förväntas ha ett argument inte har något. Om ett program t ex ska kunna ta optionerna -c och -O, samt optionen -o filnamn ska funktionen anropas med
main(int argc, char *argv)
{
    int c;
    extern char *optarg;
    extern int optind;
    . . .

    outfile = stdout;

    while ((c = getopt(argc, argv, "cOo:")) != -1)
        switch (c) {
        case 'c': objcodeonly++; break;
        case 'O': optimize++; break;
        case 'o':
                if ((outfile = fopen(optarg, "w")) == NULL) {
                    perror(optarg);
                    exit(1);
                }
                break;
        case '?': errflg++; break;
        }
    if (errflg) {
        fprintf(stderr, "usage: . . . ");
        exit(2);
    }
    for (; optind < argc; optind++) {
        if ((infile = fopen(argv[optind], "r")) == NULL) {
            perror(optarg);
            exit(3);
        }
        process(infile, outfile);
    }
}

Uppgift 5 (12 p)

Beskriv vad som karaktäriserar följande synkroniseringsprimitiv. Beskriv hur synkronisering går till, vilka data som utbyts etc.
a) Busy waiting
b) Shared Variables
c) Semaforer
d) Monitorer
e) Meddelandeöverföring
f) Remote procedure call

Uppgift 6 (4 p)

Skriv ett C-fragment som använder standardfunktionen qsort för att sortera arrayen infoarr med avseende på nyckelvärdet key:
typedef struct infostruct {
                char key[KEYLEN];
                int  value;
                char *name;
                char *secno;
            } infotype;

infotype infoarr[INFOLEN];

Uppgift 7 (4 p)

Vad är det för skillnad mellan pekarvariabler och arrayer i C? Hur och var sker minnesallokering?

Uppgift 8 (6 p)

a) Rita en bild av datastrukturen a[ ] med pilar som markerar hur pekarvärden är satta.
b) Vad skrivs ut av programmet?
#include    

#define   PR(format,value) \
            printf(#value " = %" #format "\t", (value))
#define   NL                  putchar(`\n')
#define   PRINT1(f,x1)        PR(f,x1), NL
#define   PRINT2(f,x1,x2)     PR(f,x1), PRINT1(f,x2)
#define   PRINT3(f,x1,x2,x3)  PR(f,x1), PRINT2(f,x2,x3)

struct s1 {
    char *s;
    int i;
    struct s1 *s1p;
};

main()
{
    static struct s1 a[] = {
        { "abcd", 1, a + 1 },
        { "efgh", 2, a + 2 },
        { "ijkl", 3, a }
    };

    struct s1 *p = a;
    int i;

    PRINT3(s, a[0].s, p->s, a[2].s1p->s);

    for (i = 0; i < 2; i++) {
        PR(d, --a[i].i);
        PR(c, a[i].s[3] + 1);
        NL;
    }

    PRINT3(s, ++(p->s), a[(++p)->i].s, a[--(p->s1p->i)].s);
}