* Advanced Programming in the Unix Environment [Stevens]
@ 2002-08-30 15:04 Ibraheem Umaru-Mohammed
2002-08-30 18:53 ` Glynn Clements
0 siblings, 1 reply; 4+ messages in thread
From: Ibraheem Umaru-Mohammed @ 2002-08-30 15:04 UTC (permalink / raw)
To: linux-c-programming
So, I was going through some of the exercises in the said book. Came
across Exercise 3.2, which states the following:
,----[ Exercise 3.2 ]
| Write your own function called dup2 that performs the same service
| as the dup2 function we described in Section 3.12, without calling
| the fcntl function. Be sure to handle errors correctly.
`----
Is there some sort of function that I don't know of that opens a file on a
specified file descriptor? If not, am not seeing how this can be done,
since open returns the lowest available file descriptor - that is we
can't specify the second argument to dup2 to an open function. I noticed
fdopen(), but that associates a stream with an *existing* file
descriptor. Can someone help [1] ?
Kindest regards,
--ibz.
[1] - The answer is not at the back of the book. :(
--
Ibraheem Umaru-Mohammed
"ibz"
umarumohammed (at) btinternet (dot) com
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: Advanced Programming in the Unix Environment [Stevens]
2002-08-30 15:04 Advanced Programming in the Unix Environment [Stevens] Ibraheem Umaru-Mohammed
@ 2002-08-30 18:53 ` Glynn Clements
2002-08-30 21:35 ` Ibraheem Umaru-Mohammed
0 siblings, 1 reply; 4+ messages in thread
From: Glynn Clements @ 2002-08-30 18:53 UTC (permalink / raw)
To: Ibraheem Umaru-Mohammed; +Cc: linux-c-programming
Ibraheem Umaru-Mohammed wrote:
> So, I was going through some of the exercises in the said book. Came
> across Exercise 3.2, which states the following:
>
> ,----[ Exercise 3.2 ]
> | Write your own function called dup2 that performs the same service
> | as the dup2 function we described in Section 3.12, without calling
> | the fcntl function. Be sure to handle errors correctly.
> `----
>
> Is there some sort of function that I don't know of that opens a file on a
> specified file descriptor? If not, am not seeing how this can be done,
> since open returns the lowest available file descriptor - that is we
> can't specify the second argument to dup2 to an open function. I noticed
> fdopen(), but that associates a stream with an *existing* file
> descriptor. Can someone help [1] ?
Functions which allocate descriptors always (AFAIK) use the lowest
unused descriptor. Certainly, dup() behaves this way. So, you could
implement dup2() along the following lines:
1. Call close() on the destination descriptor (the one specified by
the second argument), to ensure that it is available.
2. Repeatedly call open("/dev/null", O_RDONLY), to "consume" any
lower-numbered descriptors. Stop when open() returns the desired
descriptor number. Keep track of the descriptors thus allocated, for
use in step 5.
3. Call close() (again) on the destination descriptor.
4. Call dup() on the source descriptor; this is guaranteed to return
the destination descriptor (notwithstanding potential race conditions
in a multi-threaded program).
5. Call close() on the descriptors which were allocated in step 2,
apart from the last one, which is the destination descriptor.
--
Glynn Clements <glynn.clements@virgin.net>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: Advanced Programming in the Unix Environment [Stevens]
2002-08-30 18:53 ` Glynn Clements
@ 2002-08-30 21:35 ` Ibraheem Umaru-Mohammed
2002-08-31 0:00 ` Glynn Clements
0 siblings, 1 reply; 4+ messages in thread
From: Ibraheem Umaru-Mohammed @ 2002-08-30 21:35 UTC (permalink / raw)
To: Glynn Clements; +Cc: linux-c-programming
["Glynn Clements"="Glynn"]
Glynn >>
Glynn >> Ibraheem Umaru-Mohammed wrote:
Glynn >>
Glynn >> > So, I was going through some of the exercises in the said book. Came
Glynn >> > across Exercise 3.2, which states the following:
Glynn >> >
Glynn >> > ,----[ Exercise 3.2 ]
Glynn >> > | Write your own function called dup2 that performs the same service
Glynn >> > | as the dup2 function we described in Section 3.12, without calling
Glynn >> > | the fcntl function. Be sure to handle errors correctly.
Glynn >> > `----
Glynn >> >
Glynn >> > Is there some sort of function that I don't know of that opens a file on a
Glynn >> > specified file descriptor? If not, am not seeing how this can be done,
Glynn >> > since open returns the lowest available file descriptor - that is we
Glynn >> > can't specify the second argument to dup2 to an open function. I noticed
Glynn >> > fdopen(), but that associates a stream with an *existing* file
Glynn >> > descriptor. Can someone help [1] ?
Glynn >>
Glynn >> Functions which allocate descriptors always (AFAIK) use the lowest
Glynn >> unused descriptor. Certainly, dup() behaves this way. So, you could
Glynn >> implement dup2() along the following lines:
Glynn >>
Glynn >> 1. Call close() on the destination descriptor (the one specified by
Glynn >> the second argument), to ensure that it is available.
Glynn >>
Glynn >> 2. Repeatedly call open("/dev/null", O_RDONLY), to "consume" any
Glynn >> lower-numbered descriptors. Stop when open() returns the desired
Glynn >> descriptor number. Keep track of the descriptors thus allocated, for
Glynn >> use in step 5.
Glynn >>
Glynn >> 3. Call close() (again) on the destination descriptor.
Glynn >>
Glynn >> 4. Call dup() on the source descriptor; this is guaranteed to return
Glynn >> the destination descriptor (notwithstanding potential race conditions
Glynn >> in a multi-threaded program).
Glynn >>
Glynn >> 5. Call close() on the descriptors which were allocated in step 2,
Glynn >> apart from the last one, which is the destination descriptor.
Glynn >>
I see. I guess it can be done - but not very elegantly. dup2() is
not the same as a close() and fcntl() because dup2() does the close and
dup'licating atomically. I thought, the question was hinting at a
solution that wasn't atomic, but was a little more elegant than
exhausting the lower-numbered descriptors below the descriptor we want
to dup to.
Presumably the issue isn't only the race condition on calling dup()
after the call to close() in step 3, but I guess there is a potential problem
if another thread opens a file descriptor in the "available window"
before we do, and then close()'s it again _before_ we call dup() in step
4. So I guess there are multiple race conditions...A nasty exercise to do
so early in the book.
Anyway, thanks for the response.
Kindest regards,
--ibz.
--
Ibraheem Umaru-Mohammed
"ibz"
umarumohammed (at) btinternet (dot) com
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: Advanced Programming in the Unix Environment [Stevens]
2002-08-30 21:35 ` Ibraheem Umaru-Mohammed
@ 2002-08-31 0:00 ` Glynn Clements
0 siblings, 0 replies; 4+ messages in thread
From: Glynn Clements @ 2002-08-31 0:00 UTC (permalink / raw)
To: Ibraheem Umaru-Mohammed; +Cc: linux-c-programming
Ibraheem Umaru-Mohammed wrote:
> I see. I guess it can be done - but not very elegantly. dup2() is
> not the same as a close() and fcntl() because dup2() does the close and
> dup'licating atomically. I thought, the question was hinting at a
> solution that wasn't atomic, but was a little more elegant than
> exhausting the lower-numbered descriptors below the descriptor we want
> to dup to.
No. The only "equivalent" to dup2() is fcntl(F_DUPFD), which the
exercise specifically prohibits (otherwise it would be easy); no other
operations allow you to choose the resulting descriptor. If you can't
use either of those, you're limited to using tricks to force dup() to
use the desired descriptor.
> Presumably the issue isn't only the race condition on calling dup()
> after the call to close() in step 3, but I guess there is a potential problem
> if another thread opens a file descriptor in the "available window"
> before we do, and then close()'s it again _before_ we call dup() in step
> 4. So I guess there are multiple race conditions...A nasty exercise to do
> so early in the book.
I presume that there was an implicit assumption that the program was
single threaded (the book doesn't cover threads at all).
Atomicity can't be "manufactured". If an operation needs to be atomic,
it has to be implemented by the kernel as an atomic operation.
--
Glynn Clements <glynn.clements@virgin.net>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2002-08-31 0:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-08-30 15:04 Advanced Programming in the Unix Environment [Stevens] Ibraheem Umaru-Mohammed
2002-08-30 18:53 ` Glynn Clements
2002-08-30 21:35 ` Ibraheem Umaru-Mohammed
2002-08-31 0:00 ` Glynn Clements
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).