4.2.32 · D5 · HinglishOperating Systems
Question bank — File operations — open, read, write, seek, close
4.2.32 · D5· Coding › Operating Systems › File operations — open, read, write, seek, close
Shuru karne se pehle, teen actors se milo jinpar yahan har question tika hua hai — neeche ki picture dekho, phir labels padho.

Recall Teen actors (agar bhool gaye ho toh unfold karo)
- Actor A — file descriptor. Ek file descriptor ek chhota non-negative integer hota hai — ek claim ticket jo tumhare process ke File descriptor table ko index karta hai. Figure mein yeh left side ka numbered slot hai.
- Actor B — open file description. Us ticket ke peeche hoti hai open file description, jiska sabse important field hai offset (woh byte position jahan agla
read/writeland karta hai). Yeh figure mein beech wala box hai. - Actor C — kernel boundary. Bytes ka har asli transfer System calls and the kernel boundary cross karta hai — tum kernel se request karte ho, disk ko directly kabhi nahi chhuate. Yeh woh dashed line hai jo tumhare program aur disk ko alag karti hai.

Agle do figures do sabse tricky edge cases ko visual banate hain — sparse file ka hole aur O_APPEND ki atomicity. Jab woh questions aayein toh in par wapas aana.


True ya false — justify karo
Neeche sab kuch Statement ::: Verdict + kyun format mein hai. Pehle decide karo, phir reveal karo.
read ka 0 return karna ek error signal karta hai jise -1 ki tarah handle karna chahiye.
False.
0 ka matlab hai EOF (end of file) — ek normal, successful "kuch nahi bacha" result; sirf -1 error hai. EOF ko error treat karna copy loops ko jaldi quit ya crash karwa deta hai.read(fd, buf, 100) ke baad tum buf ke saare 100 bytes safely inspect kar sakte ho.
False. Sirf pehle
n bytes (return value, figure s02 dekho) valid hain; baki tail mein uninitialised garbage ho sakta hai. Apna use hamesha n se bound karo, count se kabhi nahi.lseek slow hai kyunki yeh physically disk read head ko reposition karta hai.
False.
lseek sirf in-kernel offset integer ko update karta hai — koi bytes nahi hilte, koi head nahi hilta. Yeh essentially free hai; actual head movement (agar koi ho) agले read/write par lazily hoti hai.Ek hi file ko do baar open karne par do fds milte hain jo ek offset share karte hain.
False. Do alag
open calls do independent open file descriptions banate hain, har ek ka apna offset hota hai. Ek se read karna doosre ko advance nahi karta. (Sharing sirf dup/fork se hoti hai.)Ek single write(fd, buf, count) hamesha exactly count bytes ek regular file mein likhta hai.
False. Ek short write ho sakta hai (disk full, koi interrupting signal, ya pipe/socket buffer full hona), isliye
n < count legal hai. Production code tab tak loop karta hai jab tak total == count na ho jaaye.O_WRONLY akela file create kar dega agar woh exist na kare.
False. O_CREAT ke bina missing file par
open fail ho jaata hai -1 ke saath aur errno = ENOENT. O_WRONLY sirf access mode choose karta hai, creation nahi.mode argument (jaise 0644) har open par permissions set karta hai.
False.
mode tab hi consult hota hai jab file actually create ho rahi ho (yaani O_CREAT diya gaya tha aur file absent thi). Existing file par yeh completely ignore hota hai.close(fd) guarantee karta hai ki tumhara data physical disk par safely hai.
Mostly false.
close kernel buffers ko storage ki taraf flush karta hai aur description free karta hai, lekin OS abhi bhi data apne write-back cache mein rakh sakta hai. Sirf fsync platter tak durability guarantee karta hai.stdin, stdout, stderr C ki language features hain, real fds nahi.
False. Yeh ordinary file descriptors 0, 1, 2 hain jinhe shell tumhara program shuru hone se pehle wire up karta hai.
write(1, ...) aur printf ultimately usi fd 1 pe hit karte hain.O_NONBLOCK ke saath khule fd par read tab tak block karta hai jab tak data na aaye.
False.
O_NONBLOCK ka poora point hi block na karna hai: agar koi data ready nahi hai toh yeh -1 return karta hai errno = EAGAIN (a.k.a. EWOULDBLOCK) ke saath, jo kehta hai baad mein try karo.Error dhundho
Har line buggy code ya reasoning describe karti hai; flaw aur fix batao.
char buf[100]; read(fd, buf, 100); write(1, buf, 100); — pehle 100 bytes copy karo.
Bug: yeh
100 likhta hai return value n ki jagah. Short/last read par, bytes n..99 garbage hain. Fix: n = read(...) capture karo aur write(1, buf, n) karo.while (read(fd, buf, N) > 0) write(out, buf, N); — poori file copy karo.
Bug: aakhri read usually
n < N return karta hai, lekin loop ek fixed N likhta hai, garbage append karta hua. Fix: n store karo aur har iteration mein n bytes likho.if (open("x", O_RDONLY) < 0) perror("open"); phir baad mein fd use karna.
Bug: fd kabhi variable mein save nahi hua, isliye woh lost hai; baad ka use undefined/stale
fd reference karta hai. Fix: int fd = open(...) karo aur usi variable par fd < 0 test karo.fd = open("log", O_WRONLY|O_APPEND); lseek(fd, 0, SEEK_SET); write(fd, s, k); — shuru mein likho.
Bug: O_APPEND ke saath har
write atomically EOF tak re-seek karta hai (figure s04), isliye preceding lseek silently undo ho jaata hai. Fix: agar tumhe positioned writes chahiye toh O_APPEND hatao.Ek program loop mein hazaaron files open karta hai aur kabhi close nahi karta.
Bug: yeh descriptors leak karta hai; per-process table bhar jaata hai aur nayi
open calls EMFILE ke saath fail hoti hain. Fix: kaam hone par har fd close karo, ulimit and resource limits ka dhyan rakhte hue.int n = write(fd, buf, count); /* assume done */ ek network-writing tool mein.
Bug: Pipes and sockets ke liye short write common hai, isliye completion assume karna bytes drop karta hai. Fix:
buf + total advance karte hue while (total < count) loop karo.fd = open(...); ... ; close(fd); read(fd, buf, 10); — safety ke liye ek aur read.
Bug:
close ke baad fd use karna use-after-close hai; integer ko baad ke open ne kisi doosri file ko reassign kar diya hoga. Fix: kisi fd ko uske close ke baad kabhi mat chhuao.Non-blocking socket par: n = read(fd, buf, N); if (n < 0) die("read failed");.
Bug:
O_NONBLOCK ke saath, n == -1 with errno == EAGAIN/EWOULDBLOCK failure nahi hai — bas matlab hai "abhi kuch ready nahi." Fix: EAGAIN ko retry-later treat karo, sirf doosre errnos par truly die karo.Why questions
Reasoning drills — answers design explain karte hain, sirf fact nahi.
open ek random number ki jagah smallest unused fd kyon return karta hai?
Yeh shell redirection ko deterministic banata hai:
close(1) ke baad, agla open reliably fd 1 grab karta hai, jisse shells stdout ko predictably ek file par wire kar sakti hain.Kernel offset ko open file description mein kyun rakhta hai, tumhari process memory mein nahi?
Kyunki offset ko kai
read/write calls ke across survive karna hota hai aur sharing ke under consistent rehna hota hai (dup, fork); kernel iska owner hai isliye koi user-space bug file ki position corrupt nahi kar sakta.Pipe se read aksar EOF par na hote hue bhi requested se kam bytes kyon return karta hai?
Ek pipe sirf wahi deliver karta hai jo writer ne ab tak produce kiya hai;
read immediately return karta hai jo bhi ready hai, poore count ka wait nahi karta, yahi streaming ko responsive banata hai.O_APPEND guarantee kyon karta hai ki do concurrent loggers ek doosre ko clobber nahi karenge?
O_APPEND ke under har write atomically current EOF tak seek karta hai aur ek indivisible step mein likhta hai (figure s04), isliye seek aur write ke beech koi doosra writer slip in nahi kar sakta.Full disk par write outright -1 ki jagah short write kyon hai?
Kernel utne bytes likhta hai jitne fit hote hain aur woh count report karta hai; sirf tab
-1 return hota hai ENOSPC ke saath jab zero bytes bhi nahi likhे ja sake. Yeh tumhare loop ko partial progress karne aur precisely react karne deta hai.read/write ke liye System calls and the kernel boundary cross karna zaroori kyon hai?
Disk shared, protected hardware hai; sirf kernel device I/O issue kar sakta hai aur permissions enforce kar sakta hai, isliye user code transfer request karta hai instead of khud perform karne ke.
Buffered I/O (fopen/fread) exist kyon karta hai agar read/write already kaam karte hain?
Har raw syscall kernel boundary cross karta hai (costly); ek user-space buffer kai chhote
fread/fwrite calls ko few large read/write syscalls mein batch karta hai, overhead dramatically cut karta hua.Tum fd ko O_NONBLOCK ke saath kyon open karoge agar yeh EAGAIN handle karne par majboor karta hai?
Taaki ek single thread kaafi slow connections juggle kar sake bina kisi ek par freeze hue: ek non-blocking
read instantly return karta hai, ek event loop (select/poll/epoll) ko jis bhi fd pe actually ready ho use service karne deta hai.Edge cases
Parent ne jinhe hint kiya tha woh boundary situations — har ek ke through reason karo.
EOF se bahut aage position tak lseek, phir ek byte write — kya create hota hai?
Ek sparse file ek "hole" ke saath (figure s03): gap zero bytes read back karta hai lekin likhे jaane tak koi real disk blocks consume nahi karta. File ki reported size badhti hai chahe allocated storage na badhe.
lseek(fd, -10, SEEK_SET) — ek negative absolute position tak seek.
Yeh
-1 aur errno = EINVAL ke saath fail hota hai: byte offset kabhi negative nahi ho sakta, isliye SEEK_SET ke saath -10 meaningless hai. (Contrast karo SEEK_END se -4 ke saath, jo theek hai kyunki size + (-4) phir bhi non-negative hai.)Ek file par read jiska offset already EOF par hai — kya hota hai?
Yeh immediately
0 (EOF) return karta hai, kuch transfer nahi karta aur offset unchanged rehta hai; koi error nahi, bas "kuch nahi bacha."read(fd, buf, 0) — zero-count read.
Yeh
0 return karta hai aur kuch nahi karta — lekin yeh 0 no-op meaning hai, EOF nahi, isliye ek robust copy loop blindly har 0 ko end-of-file treat nahi karni chahiye agar woh zero bytes request kar sakta ho.O_NONBLOCK socket par read jab koi data ready nahi ho.
Yeh
-1 return karta hai errno = EAGAIN/EWOULDBLOCK ke saath — "block hota, toh maine nahi kiya." Yeh baad mein aane ka ek normal signal hai, abort karne ki error nahi.Ek pipe ya socket fd par lseek.
Yeh
-1 aur errno = ESPIPE ke saath fail hota hai: Pipes and sockets inherently sequential streams hain jinke koi addressable byte positions nahi hote, isliye random access undefined hai.dup se do fds — ek se read, phir doosre se.
Woh share karte hain ek hi open file description aur isliye ek offset; pehle par
read karna doosre ko dikhe position advance karta hai. (Is se contrast karo do alag open calls se, jo share nahi karte.)Ek descriptor close karo jab ek dup'd fd abhi bhi point kar raha ho.
Open file description survive karti hai kyunki uski reference count abhi bhi positive hai; kernel sirf tab flush aur free karta hai jab usse refer karne wala last fd close ho.
write mid-transfer -1 errno = EINTR ke saath return karta hai.
Ek signal ne call ko interrupt kiya isse pehle ki koi bytes move hote; sahi response hai
write retry karna, abort nahi karna — operation abhi shuru bhi nahi hua tha.Ek existing file O_CREAT | O_EXCL ke saath open karna.
open fail hota hai -1 aur errno = EEXIST ke saath. O_EXCL demand karta hai ki file naye sire se create ho, tumhe ek atomic "create only if absent" deta hai — safe lock files ki basis.