Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
0a105cdd
Commit
0a105cdd
authored
Jan 14, 2017
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Put mgt_child.c in its own "MCH" namespace.
parent
8aedf4bd
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
80 additions
and
84 deletions
+80
-84
common.h
bin/varnishd/common/common.h
+1
-1
mgt.h
bin/varnishd/mgt/mgt.h
+5
-5
mgt_acceptor.c
bin/varnishd/mgt/mgt_acceptor.c
+2
-2
mgt_child.c
bin/varnishd/mgt/mgt_child.c
+44
-52
mgt_cli.c
bin/varnishd/mgt/mgt_cli.c
+9
-9
mgt_main.c
bin/varnishd/mgt/mgt_main.c
+10
-6
mgt_param.c
bin/varnishd/mgt/mgt_param.c
+1
-1
mgt_vcl.c
bin/varnishd/mgt/mgt_vcl.c
+6
-6
mgt_storage_persistent.c
bin/varnishd/storage/mgt_storage_persistent.c
+1
-1
storage_file.c
bin/varnishd/storage/storage_file.c
+1
-1
No files found.
bin/varnishd/common/common.h
View file @
0a105cdd
...
...
@@ -63,7 +63,7 @@ int Symbol_Lookup(struct vsb *vsb, void *ptr);
/* Really belongs in mgt.h, but storage_file chokes on both */
void
mgt_child_i
nherit
(
int
fd
,
const
char
*
what
);
void
MCH_Fd_I
nherit
(
int
fd
,
const
char
*
what
);
#define ARGV_ERR(...) \
do { \
...
...
bin/varnishd/mgt/mgt.h
View file @
0a105cdd
...
...
@@ -53,11 +53,11 @@ void MAC_Arg(const char *);
void
MAC_reopen_sockets
(
struct
cli
*
);
/* mgt_child.c */
extern
pid_t
child_pid
;
int
M
GT_Run
(
void
);
void
mgt_stop_c
hild
(
void
);
void
mgt_got_f
d
(
int
fd
);
void
M
GT_Child
_Cli_Fail
(
void
);
int
MCH_Init
(
int
launch
)
;
int
M
CH_Running
(
void
);
void
MCH_Stop_C
hild
(
void
);
void
MCH_TrackHighF
d
(
int
fd
);
void
M
CH
_Cli_Fail
(
void
);
/* mgt_cli.c */
...
...
bin/varnishd/mgt/mgt_acceptor.c
View file @
0a105cdd
...
...
@@ -58,7 +58,7 @@ mac_opensocket(struct listen_sock *ls)
CHECK_OBJ_NOTNULL
(
ls
,
LISTEN_SOCK_MAGIC
);
if
(
ls
->
sock
>
0
)
{
mgt_child_i
nherit
(
ls
->
sock
,
NULL
);
MCH_Fd_I
nherit
(
ls
->
sock
,
NULL
);
AZ
(
close
(
ls
->
sock
));
}
ls
->
sock
=
VTCP_bind
(
ls
->
addr
,
NULL
);
...
...
@@ -67,7 +67,7 @@ mac_opensocket(struct listen_sock *ls)
AN
(
fail
);
return
(
fail
);
}
mgt_child_i
nherit
(
ls
->
sock
,
"sock"
);
MCH_Fd_I
nherit
(
ls
->
sock
,
"sock"
);
return
(
0
);
}
...
...
bin/varnishd/mgt/mgt_child.c
View file @
0a105cdd
...
...
@@ -52,7 +52,7 @@
#include "vlu.h"
#include "vtim.h"
pid_t
child_pid
=
-
1
;
static
pid_t
child_pid
=
-
1
;
static
struct
vbitmap
*
fd_map
;
...
...
@@ -84,19 +84,6 @@ static struct vsb *child_panic = NULL;
static
void
mgt_reap_child
(
void
);
/*---------------------------------------------------------------------
* A handy little function
*/
static
inline
void
closex
(
int
*
fd
)
{
assert
(
*
fd
>=
0
);
AZ
(
close
(
*
fd
));
*
fd
=
-
1
;
}
/*=====================================================================
* Panic string evacuation and handling
*/
...
...
@@ -127,7 +114,7 @@ mgt_panic_clear(void)
}
static
void
__match_proto__
(
cli_func_t
)
mc
f
_panic_show
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
mc
h_cli
_panic_show
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
{
(
void
)
av
;
(
void
)
priv
;
...
...
@@ -143,7 +130,7 @@ mcf_panic_show(struct cli *cli, const char * const *av, void *priv)
}
static
void
__match_proto__
(
cli_func_t
)
mc
f
_panic_clear
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
mc
h_cli
_panic_clear
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
{
(
void
)
priv
;
...
...
@@ -180,7 +167,7 @@ static int mgt_max_fd;
#define CLOSE_FD_UP_TO (mgt_max_fd + 100)
void
mgt_got_f
d
(
int
fd
)
MCH_TrackHighF
d
(
int
fd
)
{
/*
* Assert > 0, to catch bogus opens, we know where stdin goes
...
...
@@ -197,7 +184,7 @@ mgt_got_fd(int fd)
*/
void
mgt_child_i
nherit
(
int
fd
,
const
char
*
what
)
MCH_Fd_I
nherit
(
int
fd
,
const
char
*
what
)
{
assert
(
fd
>=
0
);
...
...
@@ -260,7 +247,7 @@ child_poker(const struct vev *e, int what)
MGT_Complain
(
C_ERR
,
"Unexpected reply from ping: %u %s"
,
status
,
r
);
if
(
status
!=
CLIS_COMMS
)
M
GT_Child
_Cli_Fail
();
M
CH
_Cli_Fail
();
}
free
(
r
);
return
0
;
...
...
@@ -314,13 +301,13 @@ mgt_launch_child(struct cli *cli)
/* Open pipe for mgr->child CLI */
AZ
(
pipe
(
cp
));
heritage
.
cli_in
=
cp
[
0
];
mgt_child_i
nherit
(
heritage
.
cli_in
,
"cli_in"
);
MCH_Fd_I
nherit
(
heritage
.
cli_in
,
"cli_in"
);
child_cli_out
=
cp
[
1
];
/* Open pipe for child->mgr CLI */
AZ
(
pipe
(
cp
));
heritage
.
cli_out
=
cp
[
1
];
mgt_child_i
nherit
(
heritage
.
cli_out
,
"cli_out"
);
MCH_Fd_I
nherit
(
heritage
.
cli_out
,
"cli_out"
);
child_cli_in
=
cp
[
0
];
/*
...
...
@@ -392,13 +379,13 @@ mgt_launch_child(struct cli *cli)
VSC_C_mgt
->
child_start
=
++
static_VSC_C_mgt
.
child_start
;
/* Close stuff the child got */
close
x
(
&
heritage
.
std_fd
);
close
fd
(
&
heritage
.
std_fd
);
mgt_child_i
nherit
(
heritage
.
cli_in
,
NULL
);
close
x
(
&
heritage
.
cli_in
);
MCH_Fd_I
nherit
(
heritage
.
cli_in
,
NULL
);
close
fd
(
&
heritage
.
cli_in
);
mgt_child_i
nherit
(
heritage
.
cli_out
,
NULL
);
close
x
(
&
heritage
.
cli_out
);
MCH_Fd_I
nherit
(
heritage
.
cli_out
,
NULL
);
close
fd
(
&
heritage
.
cli_out
);
child_std_vlu
=
VLU_New
(
NULL
,
child_line
,
0
);
AN
(
child_std_vlu
);
...
...
@@ -431,7 +418,7 @@ mgt_launch_child(struct cli *cli)
(
intmax_t
)
child_pid
,
p
);
free
(
p
);
child_state
=
CH_RUNNING
;
mgt_stop_c
hild
();
MCH_Stop_C
hild
();
}
else
child_state
=
CH_RUNNING
;
}
...
...
@@ -472,9 +459,9 @@ mgt_reap_child(void)
*/
mgt_cli_stop_child
();
if
(
child_cli_out
>=
0
)
close
x
(
&
child_cli_out
);
close
fd
(
&
child_cli_out
);
if
(
child_cli_in
>=
0
)
close
x
(
&
child_cli_in
);
close
fd
(
&
child_cli_in
);
/* Stop the poker */
if
(
ev_poker
!=
NULL
)
{
...
...
@@ -555,7 +542,7 @@ mgt_reap_child(void)
/* Pick up any stuff lingering on stdout/stderr */
(
void
)
child_listener
(
NULL
,
EV_RD
);
close
x
(
&
child_output
);
close
fd
(
&
child_output
);
VLU_Destroy
(
child_std_vlu
);
child_pid
=
-
1
;
...
...
@@ -581,7 +568,7 @@ mgt_reap_child(void)
*/
void
M
GT_Child
_Cli_Fail
(
void
)
M
CH
_Cli_Fail
(
void
)
{
if
(
child_state
!=
CH_RUNNING
)
...
...
@@ -603,7 +590,7 @@ MGT_Child_Cli_Fail(void)
*/
void
mgt_stop_c
hild
(
void
)
MCH_Stop_C
hild
(
void
)
{
if
(
child_state
!=
CH_RUNNING
)
...
...
@@ -616,12 +603,23 @@ mgt_stop_child(void)
mgt_reap_child
();
}
/*====================================================================
* Query if the child is running
*/
int
MCH_Running
(
void
)
{
return
(
child_pid
>
0
);
}
/*=====================================================================
* CLI commands
to start/stop child
* CLI commands
*/
static
void
__match_proto__
(
cli_func_t
)
mc
f
_server_start
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
mc
h_cli
_server_start
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
{
(
void
)
av
;
...
...
@@ -640,37 +638,33 @@ mcf_server_start(struct cli *cli, const char * const *av, void *priv)
}
static
void
__match_proto__
(
cli_func_t
)
mc
f
_server_stop
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
mc
h_cli
_server_stop
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
{
(
void
)
av
;
(
void
)
priv
;
if
(
child_state
==
CH_RUNNING
)
{
mgt_stop_c
hild
();
MCH_Stop_C
hild
();
}
else
{
VCLI_SetResult
(
cli
,
CLIS_CANT
);
VCLI_Out
(
cli
,
"Child in state %s"
,
ch_state
[
child_state
]);
}
}
/*--------------------------------------------------------------------*/
static
void
mc
f
_server_status
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
mc
h_cli
_server_status
(
struct
cli
*
cli
,
const
char
*
const
*
av
,
void
*
priv
)
{
(
void
)
av
;
(
void
)
priv
;
VCLI_Out
(
cli
,
"Child in state %s"
,
ch_state
[
child_state
]);
}
/*--------------------------------------------------------------------*/
static
struct
cli_proto
cli_child
[]
=
{
{
CLICMD_SERVER_STATUS
,
""
,
mcf_server_status
},
{
CLICMD_SERVER_START
,
""
,
mcf_server_start
},
{
CLICMD_SERVER_STOP
,
""
,
mcf_server_stop
},
{
CLICMD_PANIC_SHOW
,
""
,
mcf_panic_show
},
{
CLICMD_PANIC_CLEAR
,
""
,
mcf_panic_clear
},
static
struct
cli_proto
cli_mch
[]
=
{
{
CLICMD_SERVER_STATUS
,
""
,
mch_cli_server_status
},
{
CLICMD_SERVER_START
,
""
,
mch_cli_server_start
},
{
CLICMD_SERVER_STOP
,
""
,
mch_cli_server_stop
},
{
CLICMD_PANIC_SHOW
,
""
,
mch_cli_panic_show
},
{
CLICMD_PANIC_CLEAR
,
""
,
mch_cli_panic_clear
},
{
NULL
}
};
...
...
@@ -681,14 +675,12 @@ static struct cli_proto cli_child[] = {
*/
int
M
GT_Run
(
void
)
M
CH_Init
(
int
launch
)
{
VCLS_AddFunc
(
mgt_cls
,
MCF_AUTH
,
cli_
child
);
VCLS_AddFunc
(
mgt_cls
,
MCF_AUTH
,
cli_
mch
);
if
(
!
d_flag
&&
!
mgt_has_vcl
())
MGT_Complain
(
C_ERR
,
"No VCL loaded yet"
);
else
if
(
!
d_flag
)
{
if
(
launch
)
{
mgt_launch_child
(
NULL
);
if
(
child_state
!=
CH_RUNNING
)
return
(
2
);
...
...
bin/varnishd/mgt/mgt_cli.c
View file @
0a105cdd
...
...
@@ -82,7 +82,7 @@ mcf_banner(struct cli *cli, const char *const *av, void *priv)
VCLI_Out
(
cli
,
"
\n
"
);
VCLI_Out
(
cli
,
"Type 'help' for command list.
\n
"
);
VCLI_Out
(
cli
,
"Type 'quit' to close CLI session.
\n
"
);
if
(
child_pid
<
0
)
if
(
!
MCH_Running
()
)
VCLI_Out
(
cli
,
"Type 'start' to launch worker process.
\n
"
);
VCLI_SetResult
(
cli
,
CLIS_OK
);
}
...
...
@@ -146,12 +146,12 @@ mcf_askchild(struct cli *cli, const char * const *av, void *priv)
VSB_destroy
(
&
vsb
);
VCLI_SetResult
(
cli
,
CLIS_COMMS
);
VCLI_Out
(
cli
,
"CLI communication error"
);
M
GT_Child
_Cli_Fail
();
M
CH
_Cli_Fail
();
return
;
}
VSB_destroy
(
&
vsb
);
if
(
VCLI_ReadResult
(
cli_i
,
&
u
,
&
q
,
mgt_param
.
cli_timeout
))
M
GT_Child
_Cli_Fail
();
M
CH
_Cli_Fail
();
VCLI_SetResult
(
cli
,
u
);
VCLI_Out
(
cli
,
"%s"
,
q
);
free
(
q
);
...
...
@@ -199,12 +199,12 @@ mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...)
*
status
=
CLIS_COMMS
;
if
(
resp
!=
NULL
)
*
resp
=
strdup
(
"CLI communication error"
);
M
GT_Child
_Cli_Fail
();
M
CH
_Cli_Fail
();
return
(
CLIS_COMMS
);
}
if
(
VCLI_ReadResult
(
cli_i
,
&
u
,
resp
,
mgt_param
.
cli_timeout
))
M
GT_Child
_Cli_Fail
();
M
CH
_Cli_Fail
();
if
(
status
!=
NULL
)
*
status
=
u
;
return
(
u
==
CLIS_OK
?
0
:
u
);
...
...
@@ -280,7 +280,7 @@ mcf_auth(struct cli *cli, const char *const *av, void *priv)
return
;
}
VJ_master
(
JAIL_MASTER_LOW
);
mgt_got_f
d
(
fd
);
MCH_TrackHighF
d
(
fd
);
VCLI_AuthResponse
(
fd
,
cli
->
challenge
,
buf
);
AZ
(
close
(
fd
));
if
(
strcasecmp
(
buf
,
av
[
2
]))
{
...
...
@@ -484,7 +484,7 @@ telnet_accept(const struct vev *ev, int what)
if
(
i
<
0
)
return
(
0
);
mgt_got_f
d
(
i
);
MCH_TrackHighF
d
(
i
);
tn
=
telnet_new
(
i
);
vsb
=
sock_id
(
"telnet"
,
i
);
mgt_cli_setup
(
i
,
i
,
0
,
VSB_data
(
vsb
),
telnet_close
,
tn
);
...
...
@@ -508,7 +508,7 @@ mgt_cli_secret(const char *S_arg)
exit
(
2
);
}
VJ_master
(
JAIL_MASTER_LOW
);
mgt_got_f
d
(
fd
);
MCH_TrackHighF
d
(
fd
);
i
=
read
(
fd
,
buf
,
sizeof
buf
);
if
(
i
==
0
)
{
fprintf
(
stderr
,
"Empty secret-file
\"
%s
\"\n
"
,
S_arg
);
...
...
@@ -646,7 +646,7 @@ Marg_poker(const struct vev *e, int what)
if
(
s
<
0
)
return
(
0
);
mgt_got_f
d
(
s
);
MCH_TrackHighF
d
(
s
);
M_conn
=
vev_new
();
AN
(
M_conn
);
...
...
bin/varnishd/mgt/mgt_main.c
View file @
0a105cdd
...
...
@@ -171,7 +171,7 @@ mgt_stdin_close(void *priv)
(
void
)
priv
;
if
(
d_flag
)
{
mgt_stop_c
hild
();
MCH_Stop_C
hild
();
mgt_cli_close_all
();
if
(
pfh
!=
NULL
)
(
void
)
VPF_Remove
(
pfh
);
...
...
@@ -404,8 +404,8 @@ mgt_sigint(const struct vev *e, int what)
(
void
)
what
;
MGT_Complain
(
C_ERR
,
"Manager got SIGINT"
);
(
void
)
fflush
(
stdout
);
if
(
child_pid
>=
0
)
mgt_stop_c
hild
();
if
(
MCH_Running
()
)
MCH_Stop_C
hild
();
exit
(
0
);
}
...
...
@@ -528,7 +528,7 @@ main(int argc, char * const *argv)
* have inherited from sloppy process control daemons.
*/
VSUB_closefrom
(
STDERR_FILENO
+
1
);
mgt_got_f
d
(
STDERR_FILENO
);
MCH_TrackHighF
d
(
STDERR_FILENO
);
setbuf
(
stdout
,
NULL
);
setbuf
(
stderr
,
NULL
);
...
...
@@ -538,7 +538,7 @@ main(int argc, char * const *argv)
*/
if
(
!
C_flag
&&
!
d_flag
&&
!
F_flag
)
{
eric_fd
=
mgt_eric
();
mgt_got_f
d
(
eric_fd
);
MCH_TrackHighF
d
(
eric_fd
);
mgt_pid
=
getpid
();
}
...
...
@@ -773,7 +773,11 @@ main(int argc, char * const *argv)
mgt_cli_telnet
(
T_arg
);
mgt_SHM_Create
();
u
=
MGT_Run
();
if
(
!
d_flag
&&
!
mgt_has_vcl
())
MGT_Complain
(
C_ERR
,
"No VCL loaded yet"
);
u
=
MCH_Init
(
d_flag
?
0
:
1
);
if
(
eric_fd
>=
0
)
mgt_eric_im_done
(
eric_fd
,
u
);
...
...
bin/varnishd/mgt/mgt_param.c
View file @
0a105cdd
...
...
@@ -383,7 +383,7 @@ MCF_ParamSet(struct cli *cli, const char *param, const char *val)
if
(
cli
->
result
!=
CLIS_OK
)
{
VCLI_Out
(
cli
,
"
\n
(attempting to set param '%s' to '%s')"
,
pp
->
name
,
val
);
}
else
if
(
child_pid
>=
0
&&
pp
->
flags
&
MUST_RESTART
)
{
}
else
if
(
MCH_Running
()
&&
pp
->
flags
&
MUST_RESTART
)
{
VCLI_Out
(
cli
,
"
\n
Change will take effect when child is restarted"
);
}
else
if
(
pp
->
flags
&
MUST_RELOAD
)
{
...
...
bin/varnishd/mgt/mgt_vcl.c
View file @
0a105cdd
...
...
@@ -293,7 +293,7 @@ mgt_vcl_setstate(struct cli *cli, struct vclprog *vp, const char *vs)
if
(
vp
->
warm
==
0
)
vp
->
go_cold
=
0
;
if
(
child_pid
<
0
)
if
(
!
MCH_Running
()
)
return
(
0
);
i
=
mgt_cli_askchild
(
&
status
,
&
p
,
"vcl.state %s %d%s
\n
"
,
...
...
@@ -354,7 +354,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc,
if
(
active_vcl
==
NULL
)
active_vcl
=
vp
;
if
(
child_pid
<
0
)
if
(
!
MCH_Running
()
)
return
;
if
(
mgt_cli_askchild
(
&
status
,
&
p
,
"vcl.load %s %s %d%s
\n
"
,
...
...
@@ -552,7 +552,7 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv)
return
;
if
(
mgt_vcl_setstate
(
cli
,
vp
,
VCL_STATE_WARM
))
return
;
if
(
child_pid
>=
0
&&
if
(
MCH_Running
()
&&
mgt_cli_askchild
(
&
status
,
&
p
,
"vcl.use %s
\n
"
,
av
[
2
]))
{
VCLI_SetResult
(
cli
,
status
);
VCLI_Out
(
cli
,
"%s"
,
p
);
...
...
@@ -611,7 +611,7 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
AN
(
vp
->
warm
);
else
(
void
)
mgt_vcl_setstate
(
cli
,
vp
,
VCL_STATE_COLD
);
if
(
child_pid
>=
0
)
{
if
(
MCH_Running
()
)
{
/* XXX If this fails the child is crashing, figure that later */
(
void
)
mgt_cli_askchild
(
&
status
,
&
p
,
"vcl.discard %s
\n
"
,
av
[
2
]);
free
(
p
);
...
...
@@ -631,7 +631,7 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv)
(
void
)
av
;
(
void
)
priv
;
if
(
child_pid
>=
0
)
{
if
(
MCH_Running
()
)
{
if
(
!
mgt_cli_askchild
(
&
status
,
&
p
,
"vcl.list
\n
"
))
{
VCLI_SetResult
(
cli
,
status
);
VCLI_Out
(
cli
,
"%s"
,
p
);
...
...
@@ -713,7 +713,7 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
if
(
vpt
->
state
==
VCL_STATE_COLD
)
vpt
->
state
=
VCL_STATE_AUTO
;
(
void
)
mgt_vcl_setstate
(
cli
,
vpt
,
VCL_STATE_WARM
);
if
(
child_pid
<
0
)
if
(
!
MCH_Running
()
)
return
;
i
=
mgt_cli_askchild
(
&
status
,
&
p
,
"vcl.label %s %s
\n
"
,
av
[
2
],
av
[
3
]);
...
...
bin/varnishd/storage/mgt_storage_persistent.c
View file @
0a105cdd
...
...
@@ -225,5 +225,5 @@ smp_mgt_init(struct stevedore *parent, int ac, char * const *av)
parent
->
priv
=
sc
;
/* XXX: only for sendfile I guess... */
mgt_child_i
nherit
(
sc
->
fd
,
"storage_persistent"
);
MCH_Fd_I
nherit
(
sc
->
fd
,
"storage_persistent"
);
}
bin/varnishd/storage/storage_file.c
View file @
0a105cdd
...
...
@@ -156,7 +156,7 @@ smf_init(struct stevedore *parent, int ac, char * const *av)
parent
->
priv
=
sc
;
(
void
)
STV_GetFile
(
fn
,
&
sc
->
fd
,
&
sc
->
filename
,
"-sfile"
);
mgt_child_i
nherit
(
sc
->
fd
,
"storage_file"
);
MCH_Fd_I
nherit
(
sc
->
fd
,
"storage_file"
);
sc
->
filesize
=
STV_FileSize
(
sc
->
fd
,
size
,
&
sc
->
pagesize
,
"-sfile"
);
if
(
VFIL_allocate
(
sc
->
fd
,
(
off_t
)
sc
->
filesize
,
0
))
ARGV_ERR
(
"(-sfile) allocation error: %s
\n
"
,
strerror
(
errno
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment