Skip to content

Commit 6172983

Browse files
Pash support for FreeBSD (#309)
* Distro deps for freebsd * Hacky fix to mktemp for pash tmp files. Someone could fix it better * Fixes to log parsing on intro, interface, compiler tests * Fixed head command to match bsd * Added freebsd implementation of Linux only functions. This is not optimal * mktemp hacky fixes * Fixed ps command. Not quite sure if this is the best solution * Fixed pash setup to support freebsd * mktemp fixes on bsd [skip ci] * mktemp fix on bsd Co-authored-by: Nikos Vasilakis <[email protected]> Signed-off-by: Dimitris Karnikis <[email protected]> Signed-off-by: Nikos Vasilakis <[email protected]>
1 parent 92cbe08 commit 6172983

File tree

11 files changed

+265
-21
lines changed

11 files changed

+265
-21
lines changed

compiler/pash_ptempfile_name.sh

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
11
#!/usr/bin/env bash
2+
if type lsb_release >/dev/null 2>&1 ; then
3+
distro=$(lsb_release -i -s)
4+
elif [ -e /etc/os-release ] ; then
5+
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
6+
fi
27

3-
echo "$(mktemp --tmpdir="$PASH_TMP_PREFIX" -u pash_XXXXXXXXXX)"
8+
# convert to lowercase
9+
distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
10+
# now do different things depending on distro
11+
case "$distro" in
12+
freebsd*)
13+
# bsd is so fun :)
14+
tmp=$(TMPDIR=$PASH_TMP_PREFIX mktemp -t pash_XXXXXXXXXX)
15+
echo "${tmp}"
16+
;;
17+
*)
18+
echo "$(mktemp --tmpdir="$PASH_TMP_PREFIX" -u pash_XXXXXXXXXX)"
19+
;;
20+
esac

compiler/test_evaluation_scripts.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,26 @@ execute_tests "--assert_compiler_success" "${pipeline_microbenchmarks[@]}"
190190
#cat /tmp/a | sed 's/@/,/' > ${results_time}
191191

192192

193+
if type lsb_release >/dev/null 2>&1 ; then
194+
distro=$(lsb_release -i -s)
195+
elif [ -e /etc/os-release ] ; then
196+
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
197+
fi
198+
199+
distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
200+
# now do different things depending on distro
201+
case "$distro" in
202+
freebsd*)
203+
# change sed to gsed
204+
alias sed="gsed"
205+
sed () {
206+
gsed $@
207+
}
208+
;;
209+
*)
210+
;;
211+
esac
212+
193213
echo "group,Bash,Pash2,Pash8" > ${results_time}
194214
paste -d'@' $test_results_dir/results.time_* | sed 's\,\.\g' | sed 's\:\,\g' | sed 's\@\,\g' >> ${results_time}
195215

evaluation/intro/test.sh

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,28 @@ run_test()
4545
run_test "demo-spell.sh"
4646
run_test "hello-world.sh"
4747

48+
if type lsb_release >/dev/null 2>&1 ; then
49+
distro=$(lsb_release -i -s)
50+
elif [ -e /etc/os-release ] ; then
51+
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
52+
fi
53+
54+
distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
55+
# now do different things depending on distro
56+
case "$distro" in
57+
freebsd*)
58+
# change sed to gsed
59+
sed () {
60+
gsed $@
61+
}
62+
;;
63+
*)
64+
;;
65+
esac
66+
4867
echo "group,Bash,Pash2" > $output_dir/results.time
4968
paste $output_dir/results.time_* | sed 's\,\.\g' | sed 's\:\,\g' | sed 's/\t/,/' >> $output_dir/results.time
5069

51-
5270
echo "Below follow the identical outputs:"
5371
grep --files-with-match "are identical" "$output_dir"/*_distr.time
5472

evaluation/tests/input/setup.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@ PASH_TOP=${PASH_TOP:-$(git rev-parse --show-toplevel)}
44
. "$PASH_TOP/scripts/utils.sh"
55
cd $(dirname $0)
66

7+
distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
8+
head_sz="M"
9+
# now do different things depending on distro
10+
case "$distro" in
11+
freebsd*)
12+
head_sz="m"
13+
;;
14+
esac
15+
716
[ "$1" = "-c" ] && rm-files 1M.txt all_cmds.txt words sorted_words 10M.txt
817

918
if [ ! -f ./1M.txt ]; then
1019
curl -sf 'http://ndr.md/data/dummy/1M.txt' > 1M.txt
1120
if [ $? -ne 0 ]; then
12-
curl -sf 'http://www.gutenberg.org/files/2600/2600-0.txt' | head -c 1M > 1M.txt
21+
curl -sf 'http://www.gutenberg.org/files/2600/2600-0.txt' | head -c 1${head_sz} > 1M.txt
1322
[ $? -ne 0 ] && eexit 'cannot find 1M.txt'
1423
fi
1524
append_nl_if_not ./1M.txt

evaluation/tests/interface_tests/run.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,25 @@ else
107107
done
108108
fi
109109

110+
if type lsb_release >/dev/null 2>&1 ; then
111+
distro=$(lsb_release -i -s)
112+
elif [ -e /etc/os-release ] ; then
113+
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
114+
fi
115+
116+
distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
117+
# now do different things depending on distro
118+
case "$distro" in
119+
freebsd*)
120+
# change sed to gsed
121+
sed () {
122+
gsed $@
123+
}
124+
;;
125+
*)
126+
;;
127+
esac
128+
110129
echo "group,Bash,Pash-DRY_COMP" > $output_dir/results.time
111130
paste $output_dir/results.time_* | sed 's\,\.\g' | sed 's\:\,\g' | sed 's/\t/,/' >> $output_dir/results.time
112131

runtime/auto-split.sh

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,24 @@ n_outputs="$#"
88
# Set a default DISH_TOP in this directory if it doesn't exist
99
PASH_TOP=${PASH_TOP:-$(git rev-parse --show-toplevel)}
1010

11-
temp="$(mktemp --tmpdir -u pash_XXXXXXXXXX)"
11+
if type lsb_release >/dev/null 2>&1 ; then
12+
distro=$(lsb_release -i -s)
13+
elif [ -e /etc/os-release ] ; then
14+
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
15+
fi
16+
17+
# convert to lowercase
18+
distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
19+
# now do different things depending on distro
20+
case "$distro" in
21+
freebsd*)
22+
temp="$(TMPDIR=/tmp mktemp pash_XXXXXXXXXX)"
23+
;;
24+
*)
25+
temp="$(mktemp --tmpdir -u pash_XXXXXXXXXX)"
26+
;;
27+
esac
28+
1229

1330
cat "$input" > "$temp"
1431
total_lines=$(wc -l $temp | cut -f 1 -d ' ')

runtime/eager_lib.c

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,85 @@
11
#include "eager_lib.h"
22

3+
#ifdef __FreeBSD__
4+
#define BUF_SIZE 8192
5+
#define min(a,b) (((a)<(b))?(a):(b))
6+
void fatal
7+
(const char *err)
8+
{
9+
perror(err);
10+
abort();
11+
}
12+
13+
int std_copy(int in_fd, int out_fd, int unused, int size)
14+
{
15+
char buf[4096];
16+
int err = -1;
17+
int bytes;
18+
while( (bytes = read(in_fd, buf, size)) > 0 )
19+
{
20+
if(write(out_fd, buf, bytes) != bytes)
21+
{
22+
perror("write:");
23+
goto out;
24+
}
25+
}
26+
err = 0;
27+
out:
28+
return err;
29+
}
30+
31+
32+
ssize_t
33+
send_file(int out_fd, int in_fd, off_t *offset, size_t count)
34+
{
35+
off_t orig = 0;
36+
37+
if (offset != NULL) {
38+
/* Save current file offset and set offset to value in '*offset' */
39+
orig = lseek(in_fd, 0, SEEK_CUR);
40+
if (orig == -1)
41+
return -1;
42+
if (lseek(in_fd, *offset, SEEK_SET) == -1)
43+
return -1;
44+
}
45+
46+
size_t totSent = 0;
47+
48+
while (count > 0) {
49+
size_t toRead = min(BUF_SIZE, count);
50+
51+
char buf[BUF_SIZE];
52+
ssize_t numRead = read(in_fd, buf, toRead);
53+
if (numRead == -1)
54+
return -1;
55+
if (numRead == 0)
56+
break; /* EOF */
57+
58+
ssize_t numSent = write(out_fd, buf, numRead);
59+
if (numSent == -1)
60+
return -1;
61+
if (numSent == 0) /* Should never happen */
62+
fatal("send_file: write() transferred 0 bytes");
63+
64+
count -= numSent;
65+
totSent += numSent;
66+
}
67+
68+
if (offset != NULL) {
69+
70+
/* Return updated file offset in '*offset', and reset the file offset
71+
to the value it had when we were called. */
72+
73+
*offset = lseek(in_fd, 0, SEEK_CUR);
74+
if (*offset == -1)
75+
return -1;
76+
if (lseek(in_fd, orig, SEEK_SET) == -1)
77+
return -1;
78+
}
79+
return totSent;
80+
}
81+
#endif
82+
383
int safeOpen3(const char *pathname, int flags, mode_t mode) {
484
int fd = open(pathname, flags, mode);
585
if (fd < 0) {
@@ -77,10 +157,16 @@ int blockOpenOutput(const char *pathname) {
77157

78158
// Returns the number of bytes read, or 0 if the input was done.
79159
int readInputWriteToFile(int inputFd, int intermediateWriter, int bufferSize) {
80-
81-
ssize_t res = splice(inputFd, 0, intermediateWriter, 0, bufferSize, 0);
160+
ssize_t res =
161+
#ifdef __linux__
162+
splice(inputFd, 0, intermediateWriter, 0, bufferSize, 0);
163+
#else
164+
// https://man.openbsd.org/sosplice.9
165+
// naive implementation to match our needs, maybe we could we use sosplice, somove
166+
std_copy(inputFd, intermediateWriter, 0, bufferSize);
167+
#endif
82168
if (res < 0) {
83-
printf("Error: Couldn't read from input!\n");
169+
printf("Error: Couldn't read from inputaa!\n");
84170
exit(1);
85171
}
86172
return res;
@@ -99,7 +185,7 @@ int bufferedReadInputWriteToFile(int inputFd, int intermediateWriter, int buffer
99185

100186
inputBytesRead = read(inputFd, inputBuf, sizeof(inputBuf));
101187
if (inputBytesRead < 0) {
102-
printf("Error: Couldn't read from input!\n");
188+
printf("Error: Couldn't read from input@@!\n");
103189
exit(1);
104190
}
105191
if (inputBytesRead == 0) {
@@ -185,7 +271,14 @@ void bufferedOutputRestIntermediateFile(int outputFd, int intermediateWriter, in
185271
ssize_t safeWriteOutput(int outputFd, int intermediateReader,
186272
off_t intermediateFileDiff, int* doneWriting) {
187273
ssize_t res;
188-
res = sendfile(outputFd, intermediateReader, 0, intermediateFileDiff);
274+
res =
275+
#ifdef __linux__
276+
sendfile
277+
#else
278+
send_file
279+
#endif
280+
(outputFd, intermediateReader, 0, intermediateFileDiff);
281+
189282
if (res < 0 && errno != EAGAIN) {
190283
printf("ERROR: %s, when outputing %ld bytes!\n", strerror(errno), intermediateFileDiff);
191284
exit(1);

runtime/eager_lib.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@
1010
#include <sys/select.h>
1111
#include <unistd.h>
1212
#include <sys/time.h>
13+
#ifdef __linux__
1314
#include <sys/sendfile.h>
15+
#else
16+
#include <sys/types.h>
17+
#include <sys/socket.h>
18+
#include <sys/uio.h>
19+
#endif
1420

1521
#ifndef __DEBUG__
1622
#define __DEBUG__

runtime/wait_for_output_and_sigpipe_rest.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,25 @@
33
## TODO: Give it the output pid as an argument
44

55
wait $@
6-
pids_to_kill="$(ps --ppid $$ |awk '{print $1}' | grep -E '[0-9]')"
6+
if type lsb_release >/dev/null 2>&1 ; then
7+
distro=$(lsb_release -i -s)
8+
elif [ -e /etc/os-release ] ; then
9+
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
10+
fi
11+
12+
# convert to lowercase
13+
distro=$(printf '%s\n' "$distro" | LC_ALL=C tr '[:upper:]' '[:lower:]')
14+
# now do different things depending on distro
15+
case "$distro" in
16+
freebsd*)
17+
# not sure at all about this one
18+
pids_to_kill="$(ps -efl $$ |awk '{print $1}' | grep -E '[0-9]')"
19+
;;
20+
*)
21+
pids_to_kill="$(ps --ppid $$ |awk '{print $1}' | grep -E '[0-9]')"
22+
;;
23+
esac
724
for pid in $pids_to_kill
825
do
9-
(> /dev/null 2>&1 kill -SIGPIPE $pid || true)
26+
(> /dev/null 2>&1 kill -SIGPIPE $pid || true)
1027
done

scripts/distro-deps.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ LOG_DIR=$PWD/install_logs
1010
mkdir -p $LOG_DIR
1111

1212
if [[ $(uname) == 'Darwin' ]]; then
13-
echo 'Currently pash can run only on Linux'
14-
exit 1
13+
echo 'Currently pash can run only on Linux'
14+
exit 1
1515
fi
1616

1717

1818
if type lsb_release >/dev/null 2>&1 ; then
19-
distro=$(lsb_release -i -s)
19+
distro=$(lsb_release -i -s)
2020
elif [ -e /etc/os-release ] ; then
21-
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
21+
distro=$(awk -F= '$1 == "ID" {print $2}' /etc/os-release)
2222
fi
2323

2424
# convert to lowercase
@@ -52,5 +52,11 @@ case "$distro" in
5252
echo "|-- running pacman install...."
5353
yes | pacman -S git libtool m4 automake curl pkg-config python-pip libffi make autoconf gcc10 sudo inetutils bc
5454
;;
55+
freebsd*)
56+
echo "Updating mirros"
57+
pkg update &> $LOG_DIR/pkg_update.log
58+
echo "|-- running pkg install...."
59+
yes | pkg install libtool m4 automake curl libffi py38-pip autoconf gcc gsed gmake
60+
;;
5561
*) echo "unknown distro: '$distro'" ; exit 1 ;;
5662
esac

0 commit comments

Comments
 (0)