Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #120911 > unrolled thread
| Started by | wij <wyniijj5@gmail.com> |
|---|---|
| First post | 2024-11-19 10:38 +0800 |
| Last post | 2024-11-22 00:32 +0800 |
| Articles | 20 — 8 participants |
Back to article view | Back to comp.lang.c++
How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-19 10:38 +0800
Re: How to make the Process ctor work for different R type? red floyd <no.spam.here@its.invalid> - 2024-11-18 20:34 -0800
Re: How to make the Process ctor work for different R type? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-11-19 01:04 -0500
Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-19 08:27 +0000
Re: How to make the Process ctor work for different R type? Paavo Helde <eesnimi@osa.pri.ee> - 2024-11-19 10:45 +0200
Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-19 09:15 +0000
Re: How to make the Process ctor work for different R type? red floyd <no.spam.here@its.invalid> - 2024-11-20 07:23 -0800
Re: How to make the Process ctor work for different R type? scott@slp53.sl.home (Scott Lurndal) - 2024-11-20 15:47 +0000
Re: How to make the Process ctor work for different R type? Sam <sam@email-scan.com> - 2024-11-19 07:07 -0500
Re: How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-19 21:16 +0800
Re: How to make the Process ctor work for different R type? Paavo Helde <eesnimi@osa.pri.ee> - 2024-11-19 16:15 +0200
Re: How to make the Process ctor work for different R type? Sam <sam@email-scan.com> - 2024-11-20 07:51 -0500
Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-19 16:13 +0100
Re: How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-20 00:30 +0800
Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-19 17:42 +0100
Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-21 15:27 +0100
Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-21 16:11 +0000
Re: How to make the Process ctor work for different R type? Bonita Montero <Bonita.Montero@gmail.com> - 2024-11-21 17:59 +0100
Re: How to make the Process ctor work for different R type? Muttley@DastartdlyHQ.org - 2024-11-22 09:54 +0000
Re: How to make the Process ctor work for different R type? wij <wyniijj5@gmail.com> - 2024-11-22 00:32 +0800
| From | wij <wyniijj5@gmail.com> |
|---|---|
| Date | 2024-11-19 10:38 +0800 |
| Subject | How to make the Process ctor work for different R type? |
| Message-ID | <c7d5064e0ec2f7720f1b6cef381666cfbf249cdb.camel@gmail.com> |
struct Process {
template<typename R>
explicit Process(R (*pfunc)(), bool ret_int=false) {
int pid= fork();
if(pid==-1) {
throw "Error";
}
if(pid==0) {
if(ret_int) {
_exit( pfunc() ); // error: invalid use of void expression
} else {
pfunc(); // ret value ignored
_exit(0);
}
}
};
}
The issue is _exit(int) require int type.
void f();
Process proc(f); // error: R is void
So, how to make the Process ctor work for different R type?
[toc] | [next] | [standalone]
| From | red floyd <no.spam.here@its.invalid> |
|---|---|
| Date | 2024-11-18 20:34 -0800 |
| Message-ID | <vhh4h4$1mb2b$1@redfloyd.dont-email.me> |
| In reply to | #120911 |
On 11/18/2024 6:38 PM, wij wrote:
> struct Process {
> template<typename R>
> explicit Process(R (*pfunc)(), bool ret_int=false) {
> int pid= fork();
> if(pid==-1) {
> throw "Error";
> }
> if(pid==0) {
> if(ret_int) {
> _exit( pfunc() ); // error: invalid use of void expression
> } else {
> pfunc(); // ret value ignored
> _exit(0);
> }
> }
> };
> }
>
> The issue is _exit(int) require int type.
>
> void f();
> Process proc(f); // error: R is void
>
> So, how to make the Process ctor work for different R type?
>
Google for "template specialization".
Also, use exit(), not _exit(). The former is ISO C++, the latter
is not.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2024-11-19 01:04 -0500 |
| Message-ID | <vhh9p7$1mspa$1@dont-email.me> |
| In reply to | #120912 |
On 11/18/24 23:34, red floyd wrote: ... > Also, use exit(), not _exit(). The former is ISO C++, the latter > is not. Note, however, that _Exit() has been part of ISO C++'s version of the C standard library since 2011. It was originally added in C99, and _exit() was added to POSIX in 2001, and is defined as equivalent to _Exit().
[toc] | [prev] | [next] | [standalone]
| From | Muttley@DastartdlyHQ.org |
|---|---|
| Date | 2024-11-19 08:27 +0000 |
| Message-ID | <vhhi5d$1ohbv$1@dont-email.me> |
| In reply to | #120913 |
On Tue, 19 Nov 2024 01:04:23 -0500 James Kuyper <jameskuyper@alumni.caltech.edu> boring babbled: >On 11/18/24 23:34, red floyd wrote: >.... >> Also, use exit(), not _exit(). The former is ISO C++, the latter >> is not. > >Note, however, that _Exit() has been part of ISO C++'s version of the C >standard library since 2011. It was originally added in C99, and _exit() >was added to POSIX in 2001, and is defined as equivalent to _Exit(). exit() flushes buffers before the process exits (in *nix, don't know about windows), _exit() doesn't.
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2024-11-19 10:45 +0200 |
| Message-ID | <vhhj7d$1ojsj$1@dont-email.me> |
| In reply to | #120914 |
On 19.11.2024 10:27, Muttley@DastartdlyHQ.org wrote: > On Tue, 19 Nov 2024 01:04:23 -0500 > James Kuyper <jameskuyper@alumni.caltech.edu> boring babbled: >> On 11/18/24 23:34, red floyd wrote: >> .... >>> Also, use exit(), not _exit(). The former is ISO C++, the latter >>> is not. >> >> Note, however, that _Exit() has been part of ISO C++'s version of the C >> standard library since 2011. It was originally added in C99, and _exit() >> was added to POSIX in 2001, and is defined as equivalent to _Exit(). > > exit() flushes buffers before the process exits (in *nix, don't know about > windows), _exit() doesn't. > Even more importantly, exit() executes the destructors of static objects and atexit handlers, whereas _exit() does not. So, _exit() is only suitable for emergency exit in case of errors (failing to join all child threads, for example).
[toc] | [prev] | [next] | [standalone]
| From | Muttley@DastartdlyHQ.org |
|---|---|
| Date | 2024-11-19 09:15 +0000 |
| Message-ID | <vhhkvj$1p1a7$1@dont-email.me> |
| In reply to | #120915 |
On Tue, 19 Nov 2024 10:45:34 +0200 Paavo Helde <eesnimi@osa.pri.ee> boring babbled: >On 19.11.2024 10:27, Muttley@DastartdlyHQ.org wrote: >> On Tue, 19 Nov 2024 01:04:23 -0500 >> James Kuyper <jameskuyper@alumni.caltech.edu> boring babbled: >>> On 11/18/24 23:34, red floyd wrote: >>> .... >>>> Also, use exit(), not _exit(). The former is ISO C++, the latter >>>> is not. >>> >>> Note, however, that _Exit() has been part of ISO C++'s version of the C >>> standard library since 2011. It was originally added in C99, and _exit() >>> was added to POSIX in 2001, and is defined as equivalent to _Exit(). >> >> exit() flushes buffers before the process exits (in *nix, don't know about >> windows), _exit() doesn't. >> > >Even more importantly, exit() executes the destructors of static objects >and atexit handlers, whereas _exit() does not. So, _exit() is only But doesn't call the destructors of objects on the stack which IMO makes it a fairly useless halfway house. Either call all or don't call any. >suitable for emergency exit in case of errors (failing to join all child >threads, for example). Or a system shutdown where you just want to do the most important save functions then immediately die.
[toc] | [prev] | [next] | [standalone]
| From | red floyd <no.spam.here@its.invalid> |
|---|---|
| Date | 2024-11-20 07:23 -0800 |
| Message-ID | <vhkut6$59pn$1@redfloyd.dont-email.me> |
| In reply to | #120913 |
On 11/18/2024 10:04 PM, James Kuyper wrote: > On 11/18/24 23:34, red floyd wrote: > ... >> Also, use exit(), not _exit(). The former is ISO C++, the latter >> is not. > > Note, however, that _Exit() has been part of ISO C++'s version of the C > standard library since 2011. It was originally added in C99, and _exit() > was added to POSIX in 2001, and is defined as equivalent to _Exit(). Thank you. I was unaware of that.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2024-11-20 15:47 +0000 |
| Message-ID | <kwn%O.4462$rXyb.2827@fx48.iad> |
| In reply to | #120941 |
red floyd <no.spam.here@its.invalid> writes: >On 11/18/2024 10:04 PM, James Kuyper wrote: >> On 11/18/24 23:34, red floyd wrote: >> ... >>> Also, use exit(), not _exit(). The former is ISO C++, the latter >>> is not. >> >> Note, however, that _Exit() has been part of ISO C++'s version of the C >> standard library since 2011. It was originally added in C99, and _exit() >> was added to POSIX in 2001, and is defined as equivalent to _Exit(). >Thank you. I was unaware of that. POSIX also has quick_exit(), which doesn't call the registered atexit hooks, but does call registered quick_atexit hooks.
[toc] | [prev] | [next] | [standalone]
| From | Sam <sam@email-scan.com> |
|---|---|
| Date | 2024-11-19 07:07 -0500 |
| Subject | Re: How to make the Process ctor work for different R type? |
| Message-ID | <cone.1732018068.32867.86903.1000@ripper.email-scan.com> |
| In reply to | #120911 |
wij writes:
> struct Process {
> template<typename R>
> explicit Process(R (*pfunc)(), bool ret_int=false) {
> int pid= fork();
> if(pid==-1) {
> throw "Error";
> }
> if(pid==0) {
> if(ret_int) {
> _exit( pfunc() ); // error: invalid use of void expression
> } else {
> pfunc(); // ret value ignored
> _exit(0);
> }
> }
> };
> }
>
> The issue is _exit(int) require int type.
>
> void f();
> Process proc(f); // error: R is void
>
> So, how to make the Process ctor work for different R type?
For starters this has to be resolved at compile time, not run time.
Therefore you can't use ret_int, whose purpose is very obvious, because you
don't know its value until runtime. Just because it has a default value
doesn't turn it into a compile-time, constexpr value.
Fortunately there is a very convenient R here. So the first step is to get
rid of the useless `ret_int`.
template<typename R>
explicit Process(R (*pfunc)()) {
And now this becomes a boring case of constexpr if:
#include <type_traits>
// …
if constexpr(!std::is_same_v<R,void>)
_exit( pfunc() );
} else {
pfunc();
_exit(0);
}
[toc] | [prev] | [next] | [standalone]
| From | wij <wyniijj5@gmail.com> |
|---|---|
| Date | 2024-11-19 21:16 +0800 |
| Message-ID | <01b48b009dae2e61e8c73bb09dcd9bdff90ba26a.camel@gmail.com> |
| In reply to | #120917 |
On Tue, 2024-11-19 at 07:07 -0500, Sam wrote:
> wij writes:
>
> > struct Process {
> > template<typename R>
> > explicit Process(R (*pfunc)(), bool ret_int=false) {
> > int pid= fork();
> > if(pid==-1) {
> > throw "Error";
> > }
> > if(pid==0) {
> > if(ret_int) {
> > _exit( pfunc() ); // error: invalid use of void expression
> > } else {
> > pfunc(); // ret value ignored
> > _exit(0);
> > }
> > }
> > };
> > }
> >
> > The issue is _exit(int) require int type.
> >
> > void f();
> > Process proc(f); // error: R is void
> >
> > So, how to make the Process ctor work for different R type?
>
> For starters this has to be resolved at compile time, not run time.
> Therefore you can't use ret_int, whose purpose is very obvious, because you
> don't know its value until runtime. Just because it has a default value
> doesn't turn it into a compile-time, constexpr value.
>
> Fortunately there is a very convenient R here. So the first step is to get
> rid of the useless `ret_int`.
>
> template<typename R>
> explicit Process(R (*pfunc)()) {
>
> And now this becomes a boring case of constexpr if:
>
> #include <type_traits>
>
> // …
>
>
> if constexpr(!std::is_same_v<R,void>)
> _exit( pfunc() );
> } else {
> pfunc();
> _exit(0);
> }
Thanks. I need C++11 way.
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2024-11-19 16:15 +0200 |
| Message-ID | <vhi6i1$1s8lf$1@dont-email.me> |
| In reply to | #120919 |
On 19.11.2024 15:16, wij wrote:
> On Tue, 2024-11-19 at 07:07 -0500, Sam wrote:
>> wij writes:
>>
>>> struct Process {
>>> template<typename R>
>>> explicit Process(R (*pfunc)(), bool ret_int=false) {
>>> int pid= fork();
>>> if(pid==-1) {
>>> throw "Error";
>>> }
>>> if(pid==0) {
>>> if(ret_int) {
>>> _exit( pfunc() ); // error: invalid use of void expression
>>> } else {
>>> pfunc(); // ret value ignored
>>> _exit(0);
>>> }
>>> }
>>> };
>>> }
>>>
>>> The issue is _exit(int) require int type.
>>>
>>> void f();
>>> Process proc(f); // error: R is void
>>>
>>> So, how to make the Process ctor work for different R type?
>>
>> For starters this has to be resolved at compile time, not run time.
>> Therefore you can't use ret_int, whose purpose is very obvious, because you
>> don't know its value until runtime. Just because it has a default value
>> doesn't turn it into a compile-time, constexpr value.
>>
>> Fortunately there is a very convenient R here. So the first step is to get
>> rid of the useless `ret_int`.
>>
>> template<typename R>
>> explicit Process(R (*pfunc)()) {
>>
>> And now this becomes a boring case of constexpr if:
>>
>> #include <type_traits>
>>
>> // …
>>
>>
>> if constexpr(!std::is_same_v<R,void>)
>> _exit( pfunc() );
>> } else {
>> pfunc();
>> _exit(0);
>> }
>
> Thanks. I need C++11 way.
struct Process {
template<typename FUNC>
explicit Process(FUNC func) {
int pid = fork();
if (pid == -1) {
throw "Error";
}
if (pid == 0) {
_exit(func());
}
}
};
int g() {return 1;}
void f() {}
int main() {
Process proc1(g);
Process proc2([]() {f(); return 0; });
}
[toc] | [prev] | [next] | [standalone]
| From | Sam <sam@email-scan.com> |
|---|---|
| Date | 2024-11-20 07:51 -0500 |
| Subject | Re: How to make the Process ctor work for different R type? |
| Message-ID | <cone.1732107086.53104.104235.1000@ripper.email-scan.com> |
| In reply to | #120919 |
wij writes:
> >
> > if constexpr(!std::is_same_v<R,void>)
> > _exit( pfunc() );
> > } else {
> > pfunc();
> > _exit(0);
> > }
>
> Thanks. I need C++11 way.
The C++11 way would involve using specialization, and some major
refactoring, to avoid code duplication.
explicit Process::Process<void>(void (*pfunc)()) {
followed by a specialization declaration:
template<> explicit Process::Process<void>(void (*pfunc)()) {
And, as I mentioned, the common code would need to be factored out, in some
way, to avoid duplication.
Updating the compiler to something less than a decade old will probably be
much easier.
I thought about using a delegating constructor, something like:
template<> explicit Process::Process<void>(void (*pfunc)())
: Process([&]{ pfunc(); return 0; })
{
}
but this wouldn't work for the obvious reason. One could try to get this to
work with a std::function, although I think this would be somewhat tricky
for overload resolution to work correctly.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-11-19 16:13 +0100 |
| Message-ID | <vhi9s8$1t262$1@raubtier-asyl.eternal-september.org> |
| In reply to | #120911 |
Am 19.11.2024 um 03:38 schrieb wij:
> struct Process {
> template<typename R>
> explicit Process(R (*pfunc)(), bool ret_int=false) {
> int pid= fork();
> if(pid==-1) {
> throw "Error";
> }
> if(pid==0) {
> if(ret_int) {
> _exit( pfunc() ); // error: invalid use of void expression
> } else {
> pfunc(); // ret value ignored
> _exit(0);
> }
> }
> };
> }
Why do you need a generic return of the callback where you don't
use it ? Use a function<void ()> const & parameter for pfunc so
that you can attach an arbitrary C-function or lambda.
[toc] | [prev] | [next] | [standalone]
| From | wij <wyniijj5@gmail.com> |
|---|---|
| Date | 2024-11-20 00:30 +0800 |
| Message-ID | <c61944ca5039ccb36cb32f792c69e79a144107c7.camel@gmail.com> |
| In reply to | #120922 |
On Tue, 2024-11-19 at 16:13 +0100, Bonita Montero wrote:
> Am 19.11.2024 um 03:38 schrieb wij:
> > struct Process {
> > template<typename R>
> > explicit Process(R (*pfunc)(), bool ret_int=false) {
> > int pid= fork();
> > if(pid==-1) {
> > throw "Error";
> > }
> > if(pid==0) {
> > if(ret_int) {
> > _exit( pfunc() ); // error: invalid use of void expression
> > } else {
> > pfunc(); // ret value ignored
> > _exit(0);
> > }
> > }
> > };
> > }
>
> Why do you need a generic return of the callback where you don't
> use it ? Use a function<void ()> const & parameter for pfunc so
> that you can attach an arbitrary C-function or lambda.
Not sure what you are talking about (callback???).
The current function for ForkProcess to fork has to retun int (or convertible)
or Error (overloaded). Because, other types may not be sensible.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-11-19 17:42 +0100 |
| Message-ID | <vhif3n$1u1va$1@raubtier-asyl.eternal-september.org> |
| In reply to | #120924 |
>> Am 19.11.2024 um 03:38 schrieb wij:
>>> struct Process {
>>> template<typename R>
>>> explicit Process(R (*pfunc)(), bool ret_int=false) {
>>> int pid= fork();
>>> if(pid==-1) {
>>> throw "Error";
>>> }
>>> if(pid==0) {
>>> if(ret_int) {
>>> _exit( pfunc() ); // error: invalid use of void expression
>>> } else {
>>> pfunc(); // ret value ignored
>>> _exit(0);
>>> }
>>> }
>>> };
>>> }
How about that:
struct Process
{
template<typename Fn>
Process( Fn fn )
{
int pid = fork();
if( pid == -1 )
throw system_error( errno, system_category(), "fork failed" );
if( pid )
return;
if constexpr( same_as<invoke_result_t<Fn>, int> )
exit( fn() );
else
{
fn();
exit( 0 );
}
}
};
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-11-21 15:27 +0100 |
| Message-ID | <vhnfvo$m1p1$1@raubtier-asyl.eternal-september.org> |
| In reply to | #120925 |
But a proper C++-ish wrapper would look like this:
template<typename Fn>
void xfork( Fn &&&fn )
{
int pid = fork();
if( pid == -1 )
throw system_error( errno, system_category(), "fork failed" );
if( pid )
return;
if constexpr( same_as<invoke_result_t<Fn>, int> )
exit( fn() );
else
{
fn();
exit( 0 );
}
}
There's no need for a process wrapper class if you fork only.
[toc] | [prev] | [next] | [standalone]
| From | Muttley@DastartdlyHQ.org |
|---|---|
| Date | 2024-11-21 16:11 +0000 |
| Message-ID | <vhnm4a$n66i$1@dont-email.me> |
| In reply to | #120963 |
On Thu, 21 Nov 2024 15:27:59 +0100
Bonita Montero <Bonita.Montero@gmail.com> boring babbled:
>But a proper C++-ish wrapper would look like this:
>
>template<typename Fn>
>void xfork( Fn &&&fn )
^^^
What?
> if constexpr( same_as<invoke_result_t<Fn>, int> )
What?
Have you got something against simply passing std::function ?
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-11-21 17:59 +0100 |
| Message-ID | <vhnori$nk9a$1@raubtier-asyl.eternal-september.org> |
| In reply to | #120966 |
Am 21.11.2024 um 17:11 schrieb Muttley@DastartdlyHQ.org: > On Thu, 21 Nov 2024 15:27:59 +0100 > Bonita Montero <Bonita.Montero@gmail.com> boring babbled: >> But a proper C++-ish wrapper would look like this: >> >> template<typename Fn> >> void xfork( Fn &&&fn ) > ^^^ > > What? Just a typo. >> if constexpr( same_as<invoke_result_t<Fn>, int> ) > What? > Have you got something against simply passing std::function ? A std::function isn't necessary here since I don't need any type erasure with that.
[toc] | [prev] | [next] | [standalone]
| From | Muttley@DastartdlyHQ.org |
|---|---|
| Date | 2024-11-22 09:54 +0000 |
| Message-ID | <vhpkd3$14hms$1@dont-email.me> |
| In reply to | #120968 |
On Thu, 21 Nov 2024 17:59:21 +0100 Bonita Montero <Bonita.Montero@gmail.com> boring babbled: >Am 21.11.2024 um 17:11 schrieb Muttley@DastartdlyHQ.org: >> On Thu, 21 Nov 2024 15:27:59 +0100 >> Bonita Montero <Bonita.Montero@gmail.com> boring babbled: >>> But a proper C++-ish wrapper would look like this: >>> >>> template<typename Fn> >>> void xfork( Fn &&&fn ) >> ^^^ >> >> What? > >Just a typo. > >>> if constexpr( same_as<invoke_result_t<Fn>, int> ) > >> What? >> Have you got something against simply passing std::function ? > >A std::function isn't necessary here since I don't need any type erasure >with that. Gibberish.
[toc] | [prev] | [next] | [standalone]
| From | wij <wyniijj5@gmail.com> |
|---|---|
| Date | 2024-11-22 00:32 +0800 |
| Message-ID | <6d976f878d1ad19f2a7039b1f21678c9be66d358.camel@gmail.com> |
| In reply to | #120963 |
On Thu, 2024-11-21 at 15:27 +0100, Bonita Montero wrote:
> But a proper C++-ish wrapper would look like this:
>
> template<typename Fn>
> void xfork( Fn &&&fn )
> {
> int pid = fork();
> if( pid == -1 )
> throw system_error( errno, system_category(), "fork failed" );
> if( pid )
> return;
> if constexpr( same_as<invoke_result_t<Fn>, int> )
> exit( fn() );
> else
> {
> fn();
> exit( 0 );
> }
> }
>
> There's no need for a process wrapper class if you fork only.
That's what I thought. But, as I said, "C++ is a C wrapper language".
int ftask(int) {
// asdf
return 0;
};
ForkProcess fproc(ftask,1); // fork a process to run ftask(1)
----
Particularily, I just found shm_open(3), sem_open(3) on Linux seem matured.
Such simple wrapper (like ForkProcess) can be very 'powerful'. E.g. ALL
running programs in the OS are forked processes.
The following example is just a basic usage for 'advanced IPC':
------- t_mm.cpp
#include <Wy.stdio.h>
#include <Wy.unistd.h>
#include <CSCall/mman.h>
using namespace Wy;
int main(int argc, const char* argv[])
try {
Errno r;
RegFile regf1(__FILE__,O_RDWR);
off_t flen;
if((r=regf1.get_file_size(flen))!=Ok) {
WY_THROW(r);
}
// Ex1: Copy __FILE__ to "file.tmp", using mmap(2)
//
MemMap mmap1(NULL,flen,PROT_READ|PROT_WRITE,MAP_PRIVATE,regf1.fh().fd(),0);
cout << StrSeg(static_cast<const char*>(mmap1.addr()), flen);
RegFile regf2("file.tmp", O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
if((r=regf2.resize(flen))!=Ok) {
WY_THROW(r);
}
MemMap mmap2(NULL,flen,PROT_READ|PROT_WRITE,MAP_SHARED,regf2.fh().fd(),0);
::memcpy(mmap2.addr(),mmap1.addr(),flen);
if((r=Wy::msync(mmap2.addr(),flen,MS_SYNC))!=Ok) {
WY_THROW(r);
}
// Ex2: Shared memory object example
//
const char* shm_name="/shmf";
ShmFile shmf(shm_name, O_CREAT|O_EXCL|O_RDWR, 0600);
MemMap mmap3(NULL,flen, PROT_READ|PROT_WRITE, MAP_SHARED, regf1.fh().fd(), 0);
// ...Do something in the shared memory
if((r=Wy::shm_unlink(shm_name))!=Ok) {
WY_THROW(r);
}
cout << "OK" WY_ENDL;
return 0;
}
catch(const Errno& e) {
cerr << wrd(e) << WY_ENDL;
return e.c_errno();
}
catch(...) {
cerr << "main() caught(...)" WY_ENDL;
throw;
};
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web