UNIX antikke API'er

Der er en ting der ærgrer mig enormt og det er manglen på intelligent omtanke i design af programmerings interfaces i UNIX verdenen.

Det går helt fint med at åbne og lukke filer eller printe "Hello World", men når det kommer til højere niveauer er der intet fodslav og FreeBSD's /usr/ports er en enorm skamstøtte for vores manglende evne til at blive enige om hvordan ting skal gøres.

Lad mig give et simpelt eksempel: Når man skal åbne en TCP forbindelse skal man lave mindst tre funktionskald: getnameinfo(), socket() og connect(), hertil kommer så fejlhåndtering osv.

Hvorfor er der aldrig røget en funktion ind i libc der kan kaldes med to stenge "hostname" og "service" og returnere en fildescriptor eller -1 ?

Det er ikke fordi den er svær at skrive, der findes hundreder hvis ikke tusinder versioner af den funktion over det hele.

Problemet er at man ikke kan blive enige om hvem der skal bestemme hvordan den skal se ud.

Praktisk taget siden det store "SVR-V.4 skal redde verden" show er der ikke sket nogen udvikling i UNIX API'er.

Bevares, FreeBSD har lavet en masse, Linux har lavet en masse, Solaris har lavet en masse, så idag er det praktiskt taget umuligt at skrive portabel kode der kan køre på forskellige UNIX varianter.

Der er en kraftig tendens til at antage at "Linux is the new UNIX" men hvis det er tilfældet, så er vi dælme på spanden, for kvaliteten af nye systemkald og API'er i Linux er i bedste fald svingende og oftest direkte elendig. For det meste synes jeg vi klarer os en smule bedre i FreeBSD, men vi har også nogle gevaldige fusere ind imellem.

Godt API design kræver talent, erfaring OG omtanke, det er ikke nok med en eller to ud af tre.

Hvordan får vi de folk der har forstand på den slags involveret på forkant istedet for som nu, hvor de efterfølgende kan notere sig "Well, that was stupid..." ?

phk

Kommentarer (10)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Lasse Nielsen

Hvis man kigger på moderne programmeringssprog, så finder man i oftest et bibliotek der gør præcist det du beder om, som fx Javas 'new Socket("www.google.com", 80)', eller endda værktøjer på endnu højere nuveauer, som HTTPUrlConnection.

Et sådant "højt abstraktionsniveau" passer fint ind i en programmeringsplatform (hvilket moderne sprog egentlig er), men ville være spild på operativsystemniveau. Der er det nok med en måde at gøre ting på. Simple operationer der kan kombineres, aka. The Unix Way.

Der er intet der forhindrer at C's standardbibliotek indeholder funktioner der samler OS-funktionerne. Det gør de så ikke. Men det er C's skyld, ikke ikke Unix's.

Derfor er det alligvel rigtigt at API-design er svært, og gerne umuligt at omgøre hvis man fumler i første forsøg, så der er helt sikkert bunker af møg derude :)

/L

  • 0
  • 0
Poul-Henning Kamp Blogger

Bare sådan helt uden at gøre mig umage, så er der mindst følgende programmer i UNIX der har brug for at åbne en TCP forbindelse: telnet, ftp, sendmail, lpd, ssh, finger osv osv.

Selvfølgelige skal vi ikke have en GørDagensArbejde() funktion i libc, men en funktion til at åbne en TCP forbindelse mangler helt klart.

Poul-Henning

  • 0
  • 0
Esben Mose Hansen

Glibc er allerede rigelig stor. Hvis vi kunne ville jeg hellere fjerne funktioner, som f.eks. de tåbelige strn(). På BSD kunne man så meget fjerne de næsten ligeså tåbelige strl().

Alle sprog har glimrende interfaces til at oprette TCP forbindelser... fra "assemblere" ;) C til Pascal/Java til C++ til Ruby/perl/python hele vejen til sprog der er så moderne at de næsten er uanvendelige, som f.eks. Haskell :p

Hvis man vil have et skrækeksempel på hvad der sker når man putter alt i samme standard lib kan man kikke i Javas standardlib. Det er mildest talt forfærdeligt, og svært at rette op på. Kik f.eks. på Vector, eller ArrayList#get's returtype :)

  • 0
  • 0
Henrik Kramshøj Blogger

Mener du at vi skal fjerne disse to funktioner fra BSD?

strlcpy, strlcat - size-bounded string copying and concatenation

De er NETOP lavet fordi det forbedrer sikkerheden i applikationerne væsentligt. Jeg håber det er nogle andre du taler :-)

  • 0
  • 0
Kasper Revsbech

Hej Poul-Henning
Jeg ser ligesom to ting du gerne vil, en tilføjelse til socket API'en samt at der skrivers portabel kode. Jeg er måske nok naiv når jeg antager at vejen til noget sådan er at få det optaget i POSIX standarten. Dermed må man formode at det på sigt bliver understøttet in diverse operativ systemer. Jeg ved ikke om det er en urealistisk vision at arbejde for at diverse udviklingsprojekter ikke comitter kode der ikke overhaler POSIX? Kunne man f.eks. forestille sig at et projekt som Free BSD en dag siger "Alt kode fra nu af skal overholde POSIX ver.x.x og frem" ?

  • 0
  • 0
Peter Makholm

Hej Kasper,

Poul-Henning skriver "Praktisk taget siden det store "SVR-V.4 skal redde verden" show er der ikke sket nogen udvikling i UNIX API'er.".

Hele pointen er netop at der ikke sker nogen som helst samlet form for udvikling. De forskellige unixer knopskyder uden at der er er nogen der sætter sig ned og siger: "Nu laver vi en velgennemtænkt opdatering af standarden for unix".

Løsningen er ikke at fryse sig fast på en gammel standard. Løsningen er at der er nogle folk der bør sætte sig sammen og lave en ny (og så implementerer den og skubbe den ud til næste led i udviklerkæden)

  • 0
  • 0
Flemming Kjær Jensen

Hvad er det nu lige at Unix er for en størrelse? Hvad er det nu lige en standard er i kontekst af Unix? Bell Labs og Berkeley er begge forsvundet som de store trendskabere inden for Unix men deres arv er helt tydelig.

De fleste har en fornemmelse af at deres egen Unix udgave er i en eller anden grad POSIX kompatibel? Men hvor mange ved om den udgave af Unix de afvikler vi eller emacs på er Unix 03 kompatibel (http://www.unix.org/unix03.html)? Er din?

Jeg har stadig konfigurationsstumper i min .zshrc som lige når køre uname for at afgøre om jeg skal bruge /usr/ucb/ps eller /usr/bin/ps afhængigt af om man kører SunOS 4 eller Solaris 2. Ellers har jeg ikke opdaget de store forskellige i standarder.

Det burde nok være slettet for langt tid siden. Rent faktisk er det kun applikationsudviklere der bliver plaget med autoconf og automake besværgelser som opdager hvor Unices bliver meget forskellige.

De fleste open source projekter knopskyder inden for egne rammer eller bliver til nye projekter... Hvem har i dag tyngden til at definere Unix standarder og brede API'er? Ny funktionalitet skal først i brug og hvis der er tale om rimelig success så vil lignende funktionalitet implementeres næsten ens i andre lignende operativ systemer... Men kun næsten. Der skal en standard til for at få rettet ind?

Spørgsmålet må være om det er Open Group eller græsrodsbevægelser som kan få standardiseringer ført igennem. Er Unix interoperability stadig et varmt emne for de store kommercielle Unix leverandører nu hvor open source alternativer vinder stor udbredelse?

  • 0
  • 0
Dennis Krøger

Spørgsmålet er om Linux Standard Base burde udvides til Unix Standard Base, eller eventuelt deles op i flere dele, hvoraf nogen er til de spefikke Unix varianter (BSD, Linux), og nogle er fælles (Tror f.eks. ikke vi får BSD'erne og Linux'erne til at blive enige om en definition af hvad /usr/local skal og ikke skal bruges til. :))

De har i forvejen tæt samarbejde med The Open Group, som stod bag Single Unix Specification.

  • 0
  • 0
Esben Mose Hansen

Det er vel lidt off-topic, men ok:

Problemet med strlcpy er at de forkorter strenge, ofte på en måde programmøren ikke havde til hensigt. (Forestil dig evt. "DELETE FROM MY_LONG_TABLE WHERE id==? forkortet lidt uheldigt...). Med lidt snilde kan det også udnyttes til sikkerhedshuller, og generel tænders gnidsel. strcpy er skam ok hvis, og kun hvis, man ved hvor stor den streng man kopiere fra.. altså har kaldt strlen() på den på et passende tidspunkt. Men strdup er i de fleste tilfælde bedre end både strlcpy og strcpy (og lad os end ikke nævne de meget specifikke strn). Inden du farer helt i flint over det er én god grund til at undgå strl at faste buffere til strenge generelt er en dårlig ide og vane. Og str** opfordre desværre meget til netop faste buffere.

Iøvrigt der findes et ordentligt strenghåndteringslib til C. Jeg har bare så sjældent skrevet noget i C at jeg aldrig har ledt. C++ har et ok std::string, som er langt at foretrække, omend man desværre bliver nød tit at supplere den med lidt ekstra funktioner.

  • 0
  • 0
Log ind eller Opret konto for at kommentere