2013-04-03 21:04:03 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2013 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <stdio.h>
# include <fcntl.h>
# include <unistd.h>
# include "util.h"
# include "fileio.h"
# include "strv.h"
2013-04-17 17:25:02 +04:00
# include "env-util.h"
2013-09-20 01:22:59 +04:00
# include "def.h"
# include "ctype.h"
2013-04-03 21:04:03 +04:00
static void test_parse_env_file ( void ) {
2013-07-30 03:49:55 +04:00
char t [ ] = " /tmp/test-fileio-in-XXXXXX " ,
p [ ] = " /tmp/test-fileio-out-XXXXXX " ;
2013-04-03 21:04:03 +04:00
int fd , r ;
FILE * f ;
2013-04-17 17:25:02 +04:00
_cleanup_free_ char * one = NULL , * two = NULL , * three = NULL , * four = NULL , * five = NULL ,
* six = NULL , * seven = NULL , * eight = NULL , * nine = NULL , * ten = NULL ;
2013-04-03 21:56:39 +04:00
_cleanup_strv_free_ char * * a = NULL , * * b = NULL ;
2013-04-03 21:04:03 +04:00
char * * i ;
2013-04-03 21:56:39 +04:00
unsigned k ;
2013-04-03 21:04:03 +04:00
2014-01-28 16:47:35 +04:00
fd = mkostemp_safe ( p , O_RDWR | O_CLOEXEC ) ;
2013-12-12 03:06:30 +04:00
assert_se ( fd > = 0 ) ;
close ( fd ) ;
2013-07-30 03:49:55 +04:00
2014-01-28 16:47:35 +04:00
fd = mkostemp_safe ( t , O_RDWR | O_CLOEXEC ) ;
2013-04-03 21:04:03 +04:00
assert_se ( fd > = 0 ) ;
f = fdopen ( fd , " w " ) ;
assert_se ( f ) ;
fputs ( " one=BAR \n "
" # comment \n "
" # comment \n "
2013-04-18 12:15:25 +04:00
" ; comment \n "
2013-04-03 21:04:03 +04:00
" two = bar \n "
" invalid line \n "
2013-04-18 12:15:25 +04:00
" invalid line #comment \n "
2013-04-03 21:04:03 +04:00
" three = \" 333 \n "
" xxxx \" \n "
" four = \' 44 \\ \" 44 \' \n "
" five = \' 55 \\ \' 55 \' \" FIVE \" cinco \n "
" six = seis sechs \\ \n "
" sis \n "
2013-04-18 12:15:25 +04:00
" seven= \" sevenval \" #nocomment \n "
" eight=eightval #nocomment \n "
2013-04-17 17:25:02 +04:00
" export nine=nineval \n "
" ten= " , f ) ;
2013-04-03 21:04:03 +04:00
fflush ( f ) ;
fclose ( f ) ;
2014-07-03 19:50:55 +04:00
r = load_env_file ( NULL , t , NULL , & a ) ;
2013-04-17 17:25:02 +04:00
assert_se ( r > = 0 ) ;
STRV_FOREACH ( i , a )
log_info ( " Got: <%s> " , * i ) ;
2013-12-13 02:08:47 +04:00
assert_se ( streq_ptr ( a [ 0 ] , " one=BAR " ) ) ;
assert_se ( streq_ptr ( a [ 1 ] , " two=bar " ) ) ;
assert_se ( streq_ptr ( a [ 2 ] , " three=333 \n xxxx " ) ) ;
assert_se ( streq_ptr ( a [ 3 ] , " four=44 \" 44 " ) ) ;
assert_se ( streq_ptr ( a [ 4 ] , " five=55 \' 55FIVEcinco " ) ) ;
assert_se ( streq_ptr ( a [ 5 ] , " six=seis sechs sis " ) ) ;
assert_se ( streq_ptr ( a [ 6 ] , " seven=sevenval#nocomment " ) ) ;
assert_se ( streq_ptr ( a [ 7 ] , " eight=eightval #nocomment " ) ) ;
assert_se ( streq_ptr ( a [ 8 ] , " export nine=nineval " ) ) ;
assert_se ( streq_ptr ( a [ 9 ] , " ten= " ) ) ;
2013-04-17 17:25:02 +04:00
assert_se ( a [ 10 ] = = NULL ) ;
2013-07-30 03:49:55 +04:00
strv_env_clean_log ( a , " test " ) ;
2013-04-17 17:25:02 +04:00
k = 0 ;
STRV_FOREACH ( i , b ) {
log_info ( " Got2: <%s> " , * i ) ;
assert_se ( streq ( * i , a [ k + + ] ) ) ;
}
2013-04-03 21:04:03 +04:00
r = parse_env_file (
t , NULL ,
" one " , & one ,
" two " , & two ,
" three " , & three ,
" four " , & four ,
" five " , & five ,
" six " , & six ,
" seven " , & seven ,
2013-04-17 13:02:56 +04:00
" eight " , & eight ,
2013-04-17 17:25:02 +04:00
" export nine " , & nine ,
" ten " , & ten ,
2013-04-03 21:04:03 +04:00
NULL ) ;
assert_se ( r > = 0 ) ;
log_info ( " one=[%s] " , strna ( one ) ) ;
log_info ( " two=[%s] " , strna ( two ) ) ;
log_info ( " three=[%s] " , strna ( three ) ) ;
log_info ( " four=[%s] " , strna ( four ) ) ;
log_info ( " five=[%s] " , strna ( five ) ) ;
log_info ( " six=[%s] " , strna ( six ) ) ;
log_info ( " seven=[%s] " , strna ( seven ) ) ;
2013-04-17 13:02:56 +04:00
log_info ( " eight=[%s] " , strna ( eight ) ) ;
2013-04-17 17:25:02 +04:00
log_info ( " export nine=[%s] " , strna ( nine ) ) ;
log_info ( " ten=[%s] " , strna ( nine ) ) ;
2013-04-03 21:04:03 +04:00
assert_se ( streq ( one , " BAR " ) ) ;
assert_se ( streq ( two , " bar " ) ) ;
assert_se ( streq ( three , " 333 \n xxxx " ) ) ;
assert_se ( streq ( four , " 44 \" 44 " ) ) ;
assert_se ( streq ( five , " 55 \' 55FIVEcinco " ) ) ;
assert_se ( streq ( six , " seis sechs sis " ) ) ;
2013-04-18 12:15:25 +04:00
assert_se ( streq ( seven , " sevenval#nocomment " ) ) ;
assert_se ( streq ( eight , " eightval #nocomment " ) ) ;
2013-04-17 17:25:02 +04:00
assert_se ( streq ( nine , " nineval " ) ) ;
assert_se ( ten = = NULL ) ;
2013-04-03 21:04:03 +04:00
2013-07-30 03:49:55 +04:00
r = write_env_file ( p , a ) ;
2013-04-18 12:15:25 +04:00
assert_se ( r > = 0 ) ;
2014-07-03 19:50:55 +04:00
r = load_env_file ( NULL , p , NULL , & b ) ;
2013-04-18 12:15:25 +04:00
assert_se ( r > = 0 ) ;
2013-04-03 21:04:03 +04:00
unlink ( t ) ;
2013-07-30 03:49:55 +04:00
unlink ( p ) ;
2013-04-03 21:04:03 +04:00
}
2013-09-12 05:50:16 +04:00
static void test_parse_multiline_env_file ( void ) {
char t [ ] = " /tmp/test-fileio-in-XXXXXX " ,
p [ ] = " /tmp/test-fileio-out-XXXXXX " ;
int fd , r ;
FILE * f ;
_cleanup_strv_free_ char * * a = NULL , * * b = NULL ;
char * * i ;
2014-01-28 16:47:35 +04:00
fd = mkostemp_safe ( p , O_RDWR | O_CLOEXEC ) ;
2013-12-12 03:06:30 +04:00
assert_se ( fd > = 0 ) ;
close ( fd ) ;
2013-09-12 05:50:16 +04:00
2014-01-28 16:47:35 +04:00
fd = mkostemp_safe ( t , O_RDWR | O_CLOEXEC ) ;
2013-09-12 05:50:16 +04:00
assert_se ( fd > = 0 ) ;
f = fdopen ( fd , " w " ) ;
assert_se ( f ) ;
fputs ( " one=BAR \\ \n "
" VAR \\ \n "
" \t GAR \n "
" #comment \n "
" two= \" bar \\ \n "
" var \\ \n "
" \t gar \" \n "
" #comment \n "
" tri= \" bar \\ \n "
" var \\ \n "
" \t gar \" \n " , f ) ;
fflush ( f ) ;
fclose ( f ) ;
2014-07-03 19:50:55 +04:00
r = load_env_file ( NULL , t , NULL , & a ) ;
2013-09-12 05:50:16 +04:00
assert_se ( r > = 0 ) ;
STRV_FOREACH ( i , a )
log_info ( " Got: <%s> " , * i ) ;
2013-12-13 02:08:47 +04:00
assert_se ( streq_ptr ( a [ 0 ] , " one=BAR VAR \t GAR " ) ) ;
assert_se ( streq_ptr ( a [ 1 ] , " two=bar var \t gar " ) ) ;
assert_se ( streq_ptr ( a [ 2 ] , " tri=bar var \t gar " ) ) ;
2013-09-12 05:50:16 +04:00
assert_se ( a [ 3 ] = = NULL ) ;
r = write_env_file ( p , a ) ;
assert_se ( r > = 0 ) ;
2014-07-03 19:50:55 +04:00
r = load_env_file ( NULL , p , NULL , & b ) ;
2013-09-12 05:50:16 +04:00
assert_se ( r > = 0 ) ;
unlink ( t ) ;
unlink ( p ) ;
}
2013-07-19 12:02:50 +04:00
static void test_executable_is_script ( void ) {
char t [ ] = " /tmp/test-executable-XXXXXX " ;
int fd , r ;
FILE * f ;
char * command ;
2014-01-28 16:47:35 +04:00
fd = mkostemp_safe ( t , O_RDWR | O_CLOEXEC ) ;
2013-07-19 12:02:50 +04:00
assert_se ( fd > = 0 ) ;
f = fdopen ( fd , " w " ) ;
assert_se ( f ) ;
fputs ( " #! /bin/script -a -b \n goo goo " , f ) ;
fflush ( f ) ;
r = executable_is_script ( t , & command ) ;
assert_se ( r > 0 ) ;
assert_se ( streq ( command , " /bin/script " ) ) ;
free ( command ) ;
r = executable_is_script ( " /bin/sh " , & command ) ;
assert_se ( r = = 0 ) ;
r = executable_is_script ( " /usr/bin/yum " , & command ) ;
assert_se ( r > 0 | | r = = - ENOENT ) ;
if ( r > 0 ) {
assert_se ( startswith ( command , " / " ) ) ;
free ( command ) ;
}
fclose ( f ) ;
unlink ( t ) ;
}
2013-09-14 03:41:52 +04:00
static void test_status_field ( void ) {
2013-09-20 01:22:59 +04:00
_cleanup_free_ char * t = NULL , * p = NULL , * s = NULL , * z = NULL ;
unsigned long long total = 0 , buffers = 0 ;
2013-09-15 16:40:16 +04:00
int r ;
2013-09-14 03:41:52 +04:00
assert_se ( get_status_field ( " /proc/self/status " , " \n Threads: " , & t ) = = 0 ) ;
puts ( t ) ;
assert_se ( streq ( t , " 1 " ) ) ;
2013-09-15 16:40:16 +04:00
r = get_status_field ( " /proc/meminfo " , " MemTotal: " , & p ) ;
2013-09-20 01:22:59 +04:00
if ( r ! = - ENOENT ) {
assert ( r = = 0 ) ;
puts ( p ) ;
assert_se ( safe_atollu ( p , & total ) = = 0 ) ;
}
2013-09-14 03:41:52 +04:00
2013-09-18 00:50:49 +04:00
r = get_status_field ( " /proc/meminfo " , " \n Buffers: " , & s ) ;
2013-09-20 01:22:59 +04:00
if ( r ! = - ENOENT ) {
assert ( r = = 0 ) ;
puts ( s ) ;
assert_se ( safe_atollu ( s , & buffers ) = = 0 ) ;
}
2013-09-14 03:41:52 +04:00
2013-09-20 01:22:59 +04:00
if ( p & & t )
assert ( buffers < total ) ;
/* Seccomp should be a good test for field full of zeros. */
r = get_status_field ( " /proc/meminfo " , " \n Seccomp: " , & z ) ;
if ( r ! = - ENOENT ) {
assert ( r = = 0 ) ;
puts ( z ) ;
assert_se ( safe_atollu ( z , & buffers ) = = 0 ) ;
}
}
static void test_capeff ( void ) {
int pid , p ;
for ( pid = 0 ; pid < 2 ; pid + + ) {
_cleanup_free_ char * capeff = NULL ;
int r ;
r = get_process_capeff ( 0 , & capeff ) ;
log_info ( " capeff: '%s' (r=%d) " , capeff , r ) ;
if ( r = = - ENOENT | | r = = - EPERM )
return ;
assert ( r = = 0 ) ;
assert ( * capeff ) ;
p = capeff [ strspn ( capeff , DIGITS " abcdefABCDEF " ) ] ;
assert ( ! p | | isspace ( p ) ) ;
}
2013-09-14 03:41:52 +04:00
}
2014-08-16 16:19:07 +04:00
static void test_write_string_stream ( void ) {
char fn [ ] = " /tmp/test-write_string_stream-XXXXXX " ;
_cleanup_fclose_ FILE * f = NULL ;
int fd ;
char buf [ 64 ] ;
fd = mkostemp_safe ( fn , O_RDWR ) ;
assert_se ( fd > = 0 ) ;
f = fdopen ( fd , " r " ) ;
assert_se ( f ) ;
assert_se ( write_string_stream ( f , " boohoo " ) < 0 ) ;
f = fdopen ( fd , " r+ " ) ;
assert_se ( f ) ;
assert_se ( write_string_stream ( f , " boohoo " ) = = 0 ) ;
rewind ( f ) ;
assert_se ( fgets ( buf , sizeof ( buf ) , f ) ) ;
assert_se ( streq ( buf , " boohoo \n " ) ) ;
unlink ( fn ) ;
}
static void test_write_string_file ( void ) {
char fn [ ] = " /tmp/test-write_string_file-XXXXXX " ;
int fd ;
char buf [ 64 ] = { 0 } ;
fd = mkostemp_safe ( fn , O_RDWR ) ;
assert_se ( fd > = 0 ) ;
assert_se ( write_string_file ( fn , " boohoo " ) = = 0 ) ;
assert_se ( read ( fd , buf , sizeof ( buf ) ) ) ;
assert_se ( streq ( buf , " boohoo \n " ) ) ;
unlink ( fn ) ;
}
static void test_sendfile_full ( void ) {
char in_fn [ ] = " /tmp/test-sendfile_full-XXXXXX " ;
char out_fn [ ] = " /tmp/test-sendfile_full-XXXXXX " ;
_cleanup_close_ int in_fd = - 1 ;
int out_fd ;
char text [ ] = " boohoo \n foo \n \t bar \n " ;
char buf [ 64 ] = { 0 } ;
in_fd = mkostemp_safe ( in_fn , O_RDWR ) ;
assert_se ( in_fd > = 0 ) ;
out_fd = mkostemp_safe ( out_fn , O_RDWR ) ;
assert_se ( out_fd > = 0 ) ;
assert_se ( write_string_file ( in_fn , text ) = = 0 ) ;
assert_se ( sendfile_full ( out_fd , " /a/file/which/does/not/exist/i/guess " ) < 0 ) ;
assert_se ( sendfile_full ( out_fd , in_fn ) = = sizeof ( text ) - 1 ) ;
assert_se ( lseek ( out_fd , SEEK_SET , 0 ) = = 0 ) ;
assert_se ( read ( out_fd , buf , sizeof ( buf ) ) = = sizeof ( text ) - 1 ) ;
assert_se ( streq ( buf , text ) ) ;
unlink ( in_fn ) ;
unlink ( out_fn ) ;
}
2013-04-03 21:04:03 +04:00
int main ( int argc , char * argv [ ] ) {
2013-09-20 01:22:59 +04:00
log_parse_environment ( ) ;
log_open ( ) ;
2013-04-03 21:04:03 +04:00
test_parse_env_file ( ) ;
2013-09-12 05:50:16 +04:00
test_parse_multiline_env_file ( ) ;
2013-07-19 12:02:50 +04:00
test_executable_is_script ( ) ;
2013-09-14 03:41:52 +04:00
test_status_field ( ) ;
2013-09-20 01:22:59 +04:00
test_capeff ( ) ;
2014-08-16 16:19:07 +04:00
test_write_string_stream ( ) ;
test_write_string_file ( ) ;
test_sendfile_full ( ) ;
2013-09-20 01:22:59 +04:00
2013-04-03 21:04:03 +04:00
return 0 ;
}